package com.itlong.cloud.property.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import com.itlong.cloud.POJO.DTO.app.AppElevatorAuthDTO;
import com.itlong.cloud.POJO.DTO.operate.ProjectSmartCommunityStatusChangeDTO;
import com.itlong.cloud.POJO.DTO.property.*;
import com.itlong.cloud.POJO.DTO.sdk.CloudFaceApiDTO;
import com.itlong.cloud.POJO.DTO.smartcard.SmartCardSyncDataPullDTO;
import com.itlong.cloud.POJO.DTO.smartcard.SmartCardSyncDataPullUserBasisInfoDTO;
import com.itlong.cloud.POJO.DTO.smartcard.SmartCardUserUpdateDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.jd.JDCloudElevatorFaceVO;
import com.itlong.cloud.POJO.VO.jd.JDResultVO;
import com.itlong.cloud.POJO.VO.property.AppUserInfoGetVO;
import com.itlong.cloud.POJO.VO.property.AppUserPropertyInfoVO;
import com.itlong.cloud.POJO.VO.property.CheckHouseHoldByRoomVO;
import com.itlong.cloud.POJO.VO.property.PropertyUserProofAuthInfoGetVO;
import com.itlong.cloud.POJO.VO.sdk.SDKFaceUserInfoGetVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.app.dao.IAppOldHomeDao;
import com.itlong.cloud.app.dao.IAppUserLykzAccountDao;
import com.itlong.cloud.app.service.IAppLykzCloudIntercomAccountService;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.enumerate.jd.JDCodEnum;
import com.itlong.cloud.property.dao.*;
import com.itlong.cloud.property.service.IPropertyHouseHoldDeviceAuthService;
import com.itlong.cloud.property.service.IPropertyHouseHoldInfoService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.smartcard.dao.ISmartCardUserInfoDao;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.node.MapUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.random.RandomUtil;
import com.itlong.cloud.utils.string.StringUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import com.netflix.discovery.converters.Auto;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.itlong.cloud.enumerate.AppUserRoomStatusEnum.USERROOM_STATUS_AUDIT;

/**
 * <desc>
 *      操作用户信息接口实现类
 * </desc>
 * @createDate 2017/9/14
 */
@Service
@RefreshScope
public class PropertyHouseHoldInfoServiceImpl implements IPropertyHouseHoldInfoService {
    private static final Logger LOG = LoggerFactory.getLogger(PropertyHouseHoldInfoServiceImpl.class);

    //App用户信息数据库访问对象
    @Autowired
    private IPropertyAppUserInfoDao iPropertyAppUserInfoDao;

    //App用户项目信息数据库访问对象
    @Autowired
    private IPropertyAppUserProjectDao iPropertyAppUserProjectDao;

    //App用户房间信息数据库访问对象
    @Autowired
    private IPropertyAppUserRoomDao iPropertyAppUserRoomDao;

    //App用户用户关系信息数据库访问对象
    @Autowired
    private IPropertyAppAuthRelationsDao iPropertyAppAuthRelationsDao;

    @Autowired
    private IPropertyAppUserStayInHistoryDao iPropertyAppUserStayInHistoryDao;

    @Autowired
    private IPropertyVisitorPassCodeRecordDao  iPropertyVisitorPassCodeRecordDao;

    @Autowired
    private   IPropertyDeviceElevatorAuthDao  iPropertyDeviceElevatorAuthDao;

    @Autowired
    private MessageSender messageSender;

    @Autowired
    private IPropertyHouseHoldDeviceAuthService iPropertyHouseHoldDeviceAuthService;

    @Autowired
    private ISmartCardUserInfoDao iSmartCardUserInfoDao; //一卡通用户操作对象

    @Autowired
    IPropertyUserInfoDao iPropertyUserInfoDao;

    @Autowired
    IAppOldHomeDao  iAppOldHomeDao;


    @Autowired
    IAppLykzCloudIntercomAccountService iAppLykzCloudIntercomAccountService;

    @Autowired
    IPropertyHouseholdRoleDao iPropertyHouseholdRoleDao;

    @Autowired
    private IAppUserLykzAccountDao iAppUserLykzAccountDao;

    @Value("${" + PlatformConstants.LYKZ_APPID + "}")
    String LYKZ_APPID;


    /**
     * <desc>
     *      检测用户是否是项目中
     * </desc>
     *
     * @param phoneNum
     * @param projectId
     * @param roomId
     * @return
     * @author Jiaqi.X
     * @createDate 2020/03/19
     */
    @Override
    public Map<String, Object> checkUserInProject(String phoneNum, String projectId, String roomId) {
        Map<String,Object> result = iPropertyAppUserInfoDao.checkUserInProject(phoneNum,projectId,roomId);
        if(result != null && result.get("checkRoom") != null){
            result.put("checkRoom",true);
        }
        if(result != null && result.get("checkOwnerRoom") != null){
            result.put("roomExists",true);
        }
        return result;
    }

    /**
     * <desc>
     *     获取地址下的楼栋单元房间id
     * </desc>
     *
     * @param address
     * @return
     * @author Jiaqi.X
     * @createDate 2020/03/18
     */
    @Override
    public Map<String,Object> getRoomInfoByBuildNameAndUnitNameAndRoomNum(String address,String projectId){
        address = address.replace(" ", "");
        String buildName = address.substring(0, address.indexOf("-"));
        address = address.substring(address.indexOf("-") + 1, address.length());
        String unitName =  address.substring(0, address.indexOf("-"));
        address = address.substring(address.indexOf("-") + 1, address.length());
        String roomNum = StringHandlerUtil.autlSupply(4,  address.substring(address.indexOf("-", 2) + 1, address.length()), "0");
        Map<String,Object> map = iPropertyUserInfoDao.getRoomInfoByBuildNameAndUnitNameAndRoomNum(buildName,unitName,roomNum,projectId);
        return map;
    }


    /**
     * <desc>
     *      根据id获取用户信息
     * <desc/>
     *
     * @param appUserGetOneDTO 获取单个App用户信息的数据传输对象
     * @return HouseHoldDetailsInfoDTO App用户信息详情数据传输对象
     * @author zhangs
     * @createDate 2017/09/18
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public HouseHoldDetailsInfoDTO getUserById(AppUserGetOneDTO appUserGetOneDTO){
        HouseHoldDetailsInfoDTO houseHoldDetailsInfoDTO = new HouseHoldDetailsInfoDTO();
        List<AppUserPropertyInfoVO> appUserPropertyInfoVOS = new ArrayList<>();
        String projectId = appUserGetOneDTO.getProjectId();
        String userId = appUserGetOneDTO.getUserId();
        //住户项目关系数据状态,0删除 1正常 2禁用
        Integer status = DataStatusEnum.NORMAL.getType();
//        //判断住户项目关系数据状态,若无迁入状态房间则数据状态为删除
//        AppUserRoomPO appUserRoomPO = new AppUserRoomPO();
//        appUserRoomPO.setUserId(userId);
//        appUserRoomPO.setProjectId(projectId);
//        appUserRoomPO.setUserRoomStatus(AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
//        List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getCompareListByPO(appUserRoomPO);

        //查看用户时需查询用户相关地址、用户以及入住历史
        CheckAppUserDTO checkAppUserDTO = new CheckAppUserDTO();
        checkAppUserDTO.setProjectId(projectId);
        checkAppUserDTO.setUserId(userId);
        checkAppUserDTO.setStatus(status);
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("projectId", projectId);
        params.put("status", status);

        //根据App用户Id和项目Id获取App用户详情页数据传输对象(用户信息-查看)
        AppUserGetUserDetailsDTO appUserGetUserDetailsDTO = iPropertyAppUserInfoDao.getUserById(params);

        //根据App用户Id和项目Id获取App用户详情页用户相关房屋数据传输对象(用户信息-查看)
        checkAppUserDTO.setUserRoomStatus(AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        List<AppUserRoomDetailsDTO> appUserRoomDetailsDTOS =
                iPropertyAppUserRoomDao.getUserRoomList(checkAppUserDTO);

        if (appUserRoomDetailsDTOS != null && !appUserRoomDetailsDTOS.isEmpty()){

            for (AppUserRoomDetailsDTO roomDetailsDTO : appUserRoomDetailsDTOS){
                AppUserPropertyInfoVO appUserPropertyInfoVO =new AppUserPropertyInfoVO();
                BeanUtils.copyProperties(roomDetailsDTO, appUserPropertyInfoVO);
                //房屋授权
                appUserPropertyInfoVO.setAuthType("1");
                appUserPropertyInfoVOS.add(appUserPropertyInfoVO);
            }
        }
        List<Map<String, String>> roleInfoList= iPropertyHouseholdRoleDao.getUserRoleList(params);
        for (Map<String, String> roleInfo : roleInfoList){
            AppUserPropertyInfoVO appUserPropertyInfoVO =new AppUserPropertyInfoVO();
            //分组授权
            appUserPropertyInfoVO.setAuthType("2");
            appUserPropertyInfoVO.setHouserTypeName("");
            appUserPropertyInfoVO.setRoleName(roleInfo.get("roleName"));
            appUserPropertyInfoVO.setCreateTime(roleInfo.get("createTime"));
            appUserPropertyInfoVOS.add(appUserPropertyInfoVO);
        }
        houseHoldDetailsInfoDTO.setAppUserGetUserDetailsDTO(appUserGetUserDetailsDTO);
        houseHoldDetailsInfoDTO.setAppUserPropertyInfoVOS(appUserPropertyInfoVOS);
        return houseHoldDetailsInfoDTO;
    }

    /**
     * <desc>
     *      修改App用户信息时获取App用户信息
     * <desc/>
     * @RequestBody appUserGetOneDTO 获取单个App用户信息的数据传输对象
     * @return AppUserGetUserDetailsInfoDTO App用户信息更新时获取信息数据传输对象
     * @author zhangs
     * @createDate 2017/09/25
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public AppUserUpdateUserGetDTO updateUserGet(AppUserGetOneDTO appUserGetOneDTO){
        String userId = appUserGetOneDTO.getUserId();
        String projectId = appUserGetOneDTO.getProjectId();
        String userRoomStatus = appUserGetOneDTO.getUserRoomStatus();

        //App用户详情页用户基础信息数据传输对象
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("projectId", projectId);
//        params.put("status", status);
        AppUserGetUserDetailsDTO appUserGetUserDetailsDTO = iPropertyAppUserInfoDao.getUserById(params);

        //App用户详情页相关房屋数据传输对象
        CheckAppUserDTO checkAppUserDTO = new CheckAppUserDTO();
        checkAppUserDTO.setProjectId(projectId);
        checkAppUserDTO.setUserId(userId);
        checkAppUserDTO.setUserRoomStatus(Integer.parseInt(userRoomStatus));
//        checkAppUserDTO.setStatus(DataStatusEnum.NORMAL.getType());
        List<AppUserRoomDetailsDTO> appUserRoomDetailsDTOS =
                iPropertyAppUserRoomDao.getUserRoomList(checkAppUserDTO);

        //获取用户角色组列表
        List<Map<String, String>> roleInfoList= iPropertyHouseholdRoleDao.getUserRoleList(params);
        List<String> roleIdList = new ArrayList<>();
        AppUserUpdateUserGetDTO appUserUpdateUserGetDTO = new AppUserUpdateUserGetDTO(appUserGetUserDetailsDTO, appUserRoomDetailsDTOS);

        for (Map<String, String> roleInfo : roleInfoList) {
            roleIdList.add(roleInfo.get("roleId"));
        }
        appUserUpdateUserGetDTO.setRoleIdList(roleIdList);
        return appUserUpdateUserGetDTO;
    }

    /**
     * <desc>
     *      根据实体类获取用户信息
     * <desc/>
     *
     * @param appUserInfoPO App用户信息实体对象
     * @return appUserInfoPO App用户信息实体对象
     * @author zhangs
     * @createDate 2017/09/18
     */
    @Override
    public AppUserInfoPO getOneUserByPO(AppUserInfoPO appUserInfoPO){
        return null;
    }

    /**
     * <desc>
     *      App用户信息分页查询
     * <desc/>
     *
     * @param checkAppUserDTO 查询App用户信息数据传输对象
     * @return Page<CheckAppUserInfoDTO> App用户房间信息分页集
     * @author zhangs
     * @createDate 2017/09/22
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<AppUserInfoGetVO> getUserList(CheckAppUserDTO checkAppUserDTO) throws Exception{
        Page<AppUserInfoGetVO> page = new Page<>();
        String currentPage = checkAppUserDTO.getCurrentPage();
        String pageSize = checkAppUserDTO.getPageSize();
        page.getPage().setPageSize(pageSize);
        page.getPage().setCurrentPage(currentPage);

        //获取App用户相关房屋数据传输对象
//        Map<String, Object> params = this.getUserRoomPage(checkAppUserDTO);
        Map<String, Object> params = MapUtil.objectToMap(checkAppUserDTO, false);
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());

        List<AppUserInfoGetVO> appUserInfoGetVOS;
        Integer pageCount;
        if(Objects.equals(checkAppUserDTO.getUserRoomStatus(), AppUserRoomStatusEnum.USERROOM_STATUS_MOVEOUT.getType())) {
            //迁出住户。条件：需住户在该项目下所有地址全为迁出状态
            appUserInfoGetVOS = iPropertyAppUserRoomDao.getRemoveUserRoomByPageList(params);
            pageCount = iPropertyAppUserRoomDao.getRemovePageCount(params);
        } else if(Objects.equals(checkAppUserDTO.getUserRoomStatus(), AppUserRoomStatusEnum.USERROOM_STATUS_AUDIT.getType())) {
            //待审核住户(此处时间查询是指更新时间)
            String beginTime = (String) params.get("beginTime");
            if (StringUtils.isNotBlank(beginTime)) {
                params.put("updateBeginTime", beginTime);
                params.remove("beginTime");
            }
            String endTime = (String) params.get("endTime");
            if (StringUtils.isNotBlank(endTime)) {
                params.put("updateEndTime", endTime);
                params.remove("endTime");
            }
            appUserInfoGetVOS = iPropertyAppUserRoomDao.getNotAuditUserRoomByPageList(params);
            pageCount = iPropertyAppUserRoomDao.getNotAuditPageCount(params);
        } else if (Objects.equals(checkAppUserDTO.getUserRoomStatus(), AppUserRoomStatusEnum.USERROOM_STATUS_NOTAUDIT.getType())){
            //审核未通过
            appUserInfoGetVOS = iPropertyAppUserRoomDao.getUserRoomByPageList(params);
            pageCount = iPropertyAppUserRoomDao.getPageCount(params);
        } else {
            //已迁入
            params.put("status", DataStatusEnum.NORMAL.getType());
            params.put("SmartCard", DeviceAuthEnum.DEVICEAUTH_SMARTCARD.getType());
            params.put("Property", DeviceAuthEnum.DEVICEAUTH_PROPERTY.getType());
            params.put("App", DeviceAuthEnum.DEVICEAUTH_APP.getType());
            appUserInfoGetVOS = iPropertyAppUserRoomDao.getMoveInUserRoomByPageLst(params);
            pageCount = iPropertyAppUserRoomDao.getMoveInUserRoomPageCount(params);

            //迁出状态的房屋，用户列表中不拼接地址
        }
        for (AppUserInfoGetVO vo : appUserInfoGetVOS) {
            if(vo.getUserLabel()==null){
                vo.setVipFlag("0");
            }else {
                vo.setVipFlag(Arrays.asList(vo.getUserLabel().split(",")).contains("1")? "1":"0" );
            }

        }
        page.setRows(appUserInfoGetVOS, pageCount);
        return page;
    }

    /**
     * <desc>
     *      住户权限分配查询App用户信息接口
     * <desc/>
     * @param checkAppUserDTO 查询App用户信息数据传输对象
     * @return Page<CheckAppUserInfoDTO> App用户房间信息分页集
     * @author Qiang.S
     * @createDate 2020/02/21
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<AppUserInfoGetVO> getCheckUserListForHouseHold(CheckAppUserDTO checkAppUserDTO) throws Exception{
        Page<AppUserInfoGetVO> page = new Page<>();
        String currentPage = checkAppUserDTO.getCurrentPage();
        String pageSize = checkAppUserDTO.getPageSize();
        page.getPage().setPageSize(pageSize);
        page.getPage().setCurrentPage(currentPage);

        //获取App用户相关房屋数据传输对象
//        Map<String, Object> params = this.getUserRoomPage(checkAppUserDTO);
        Map<String, Object> params = MapUtil.objectToMap(checkAppUserDTO, false);
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());

        List<AppUserInfoGetVO> appUserInfoGetVOS;
        Integer pageCount;
        //已迁入
        params.put("status", DataStatusEnum.NORMAL.getType());
        params.put("SmartCard", DeviceAuthEnum.DEVICEAUTH_SMARTCARD.getType());
        params.put("Property", DeviceAuthEnum.DEVICEAUTH_PROPERTY.getType());
        params.put("App", DeviceAuthEnum.DEVICEAUTH_APP.getType());
        appUserInfoGetVOS = iPropertyAppUserRoomDao.getMoveInUserRoomByPageLstForHouseHold(params);
        pageCount = iPropertyAppUserRoomDao.getMoveInUserRoomPageCountForHouseHold(params);
        page.setRows(appUserInfoGetVOS, pageCount);
        return page;
    }

    /**
     * <desc>
     *      添加App用户信息前判断用户是否在当前项目中存在
     * <desc/>
     *
     * @param projectId  项目Id
     * @param phoneNum  App用户手机号
     * @return Integer
     * @author zhangs
     * @createDate 2017/09/26
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Integer getUserByPhoneNum(String projectId, String phoneNum) {
        Map<String, Object> param = new HashMap<>();
        param.put("projectId", projectId);
        param.put("phoneNum", phoneNum);
        List<AppUserProjectPO> appUserProjectPOS = iPropertyAppUserProjectDao.getUserAtProject(param);
        Integer result = 0;
        if (appUserProjectPOS != null && appUserProjectPOS.size() > 0) {
            result =  1;
        }
        return result;
    }


    /**
     * <desc>
     *      保存用户信息
     * </desc>
     *
     * @param appUserGetUserInfoDTO App用户信息数据传输对象
     * @param isSmartCommunity 是否开启云对讲
     * @param loginUserId 物业登录账号
     * @return
     * @author zhangs
     * @createDate 2017/09/19
     */
    @Override
//    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void saveUser(AppUserGetUserInfoDTO appUserGetUserInfoDTO, Integer isSmartCommunity, String loginUserId) throws Exception{
        //用户Id和项目Id集合。用于生成设备权限
        Map<String, Object> userIdSet = new HashMap<>();
        String projectId = appUserGetUserInfoDTO.getProjectId();

        //保存用户信息、用户房间信息以及用户项目信息有误
        String userId = this.saveUserInfoAndRelationInfoToDB(appUserGetUserInfoDTO, isSmartCommunity);
        if (StringUtils.isBlank(userId)) {
            throw new DataAccessException("保存用户信息、用户房间信息以及用户项目信息有误");
        }
        userIdSet.put("userId", userId);
        userIdSet.put("projectId", projectId);

        List<Map<String, Object>> userIdLists = new ArrayList<>();
        userIdLists.add(userIdSet);
        //获取住户当前最新的有权限地址
        List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOS =
                iPropertyHouseHoldDeviceAuthService.getUserAuthAddr(userIdLists, projectId, loginUserId);
        UserDeviceAuthAddrAndSourceDTO userDeviceAuthAddrAndSourceDTO = new UserDeviceAuthAddrAndSourceDTO();
        userDeviceAuthAddrAndSourceDTO.setUserDeviceAuthAddreddDTOS(userDeviceAuthAddreddDTOS);
        userDeviceAuthAddrAndSourceDTO.setAuthSource(DeviceAuthEnum.DEVICEAUTH_PROPERTY.getType());
        //rabbitmq 发送任务
        //LOG.info("RabbitMQ_获取用户设备权限地址_生产者:" + JSON.toJSONString(userDeviceAuthAddrAndSourceDTO));
        JSONObject dataJs = new JSONObject();
        dataJs.put("data", JSONObject.toJSON(userDeviceAuthAddrAndSourceDTO));
        this.userDeviceAuthAddressProducer(dataJs);

        List<String> userIds = new ArrayList<>();
        userIds.add(userId);

        //保存用户角色组及角色组的设备权限



        //与旺龙一卡通对接-收集云端变动数据-住户信息
        this.prepareUserBasisInfoForSyncToSmartCard(projectId, userIds, SmartCardSyncDataOperTypeEnum.ADD);
        //推送云对讲指令
//        if (ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType() == isSmartCommunity) {
            //开启云对讲的项目需推送云对讲指令
        this.sendCloudIntercomOrder(SmartCommunityEnum.PUSH_USER_ROOM, projectId, userIds);
//        }
    }

    /**
     * <desc>
     *      保存用户以及相关关系信息(用户基础信息、用户房间信息和用户项目信息)
     * </desc>
     *
     * @param appUserGetUserInfoDTO App用户信息数据传输对象
     * @param isSmartCommunity 是否开启云对讲
     * @return String
     * @author zhangs
     * @createDate 2018/02/25
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public String saveUserInfoAndRelationInfoToDB(AppUserGetUserInfoDTO appUserGetUserInfoDTO, Integer isSmartCommunity) throws Exception {
        String projectId = appUserGetUserInfoDTO.getProjectId();
        String phoneNum = appUserGetUserInfoDTO.getPhoneNum();
        //保存App用户信息。住户只有审核未通过的房间，在审核未通过删除后应该能从添加住户的入口再次添加
        AppUserInfoPO appUserInfoPO;
        //保存用户信息操作的数据数量
        Integer userInfoCount;
        Map<String, Object> params = new HashMap<>();
        params.put("projectId", projectId);
        params.put("phoneNum", phoneNum);
        List<AppUserInfoPO> appUserInfoPOS = iPropertyAppUserInfoDao.getUserInfoByPhoneNum(params);
        if (appUserInfoPOS != null && appUserInfoPOS.size() > 0) {
            //AppUserInfo 已存在.系统中只存在一条住户信息数据。已存在住户再添加时更新部分信息
            appUserInfoPO = appUserInfoPOS.get(0);
            appUserInfoPO.setRealName(appUserGetUserInfoDTO.getRealName());
            appUserInfoPO.setGender(appUserGetUserInfoDTO.getGender());
            iPropertyAppUserInfoDao.update(appUserInfoPO);
            userInfoCount = 1;
        } else {
            //AppUserInfo 不存在
            appUserInfoPO = this.getAppUserInfo(appUserGetUserInfoDTO);
            userInfoCount = iPropertyAppUserInfoDao.save(SqlUtil.durableData(appUserInfoPO, PlatformConstants.TABLE_SAVE));
        }

        //TODO 住户房间关系中的qq号(同住户项目关系中的QQ)后续(QQ物联)需要维护，维护点有添加、修改、迁入、审核通过，其他模块的邀请家人和一卡通添加住户
        String userId = appUserInfoPO.getUserId();
        //保存住户入住历史
        List<AppUserStayInHistoryPO> appUserStayInHistoryPOS = new ArrayList<>();
        AppUserStayInHistoryPO appUserStayInHistoryPO;
        //保存App用户房间信息
        Integer userRoomCount = 0;
        //整理住户房间信息
        List<AppUserRoomPO> appUserRoomPOS = this.getAppUserRoomList(appUserGetUserInfoDTO, userId);
        if((appUserRoomPOS != null) && (appUserRoomPOS.size() != 0)) {
            AppUserRoomPO appUserRoom = new AppUserRoomPO();
            appUserRoom.setProjectId(projectId);
            appUserRoom.setUserId(userId);
            //若住户存在收取未通过并且删除的房间，则部分房间应保存部分房间应更新
            List<AppUserRoomPO> appUserRoomUpdateList = new ArrayList<>();
            List<AppUserRoomPO> appUserRoomOldList = iPropertyAppUserRoomDao.getUserRoomByPO(appUserRoom);
            if (appUserRoomOldList != null && appUserRoomOldList.size() > 0) {
                Map<String, AppUserRoomPO> appUserRoomNewMap = new HashMap<>();
                //将新地址放入Map中，遍历旧住户房间集合，
                // 若roomId相同则放入待更新的集合appUserRoomUpdateList中且去除appUserRoomOldList中的
                for(AppUserRoomPO appUserRoomPO:appUserRoomPOS) {
                    appUserRoomNewMap.put(appUserRoomPO.getRoomId(), appUserRoomPO);
                }
                for (AppUserRoomPO appUserRoomOld:appUserRoomOldList) {
                    String roomIdOld = appUserRoomOld.getRoomId();
                    AppUserRoomPO appUserRoomNew = appUserRoomNewMap.get(roomIdOld);
                    if (appUserRoomNew != null) {
                        appUserRoomUpdateList.add(appUserRoomNew);
                        appUserRoomPOS.remove(appUserRoomNew);
                    }
                }
            }
            //更新
            if (appUserRoomUpdateList != null && appUserRoomUpdateList.size() > 0) {
                for (AppUserRoomPO appUserRoomPO:appUserRoomUpdateList) {
                    userRoomCount += iPropertyAppUserRoomDao.update(appUserRoomPO);

                    //保存住户入住历史
                    appUserStayInHistoryPO = new AppUserStayInHistoryPO(appUserRoomPO.getUserId(),
                            appUserRoomPO.getProjectId(), appUserRoomPO.getBuildId(), appUserRoomPO.getUnitId(), appUserRoomPO.getRoomId(),
                            appUserRoomPO.getRoomNum(), AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
                    appUserStayInHistoryPOS.add(appUserStayInHistoryPO);
                }
            }
            //添加
            if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
                ArrayList<Map<String,Object>> rowsList = new ArrayList<>() ;
                Map<String, Object> oneRowMap;
                for(AppUserRoomPO appUserRoomPO:appUserRoomPOS) {
                    oneRowMap = SqlUtil.durableData(appUserRoomPO, PlatformConstants.TABLE_SAVE);
                    rowsList.add(oneRowMap);

                    //保存住户入住历史
                    appUserStayInHistoryPO = new AppUserStayInHistoryPO(appUserRoomPO.getUserId(),
                            appUserRoomPO.getProjectId(), appUserRoomPO.getBuildId(), appUserRoomPO.getUnitId(), appUserRoomPO.getRoomId(),
                            appUserRoomPO.getRoomNum(), AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
                    appUserStayInHistoryPOS.add(appUserStayInHistoryPO);
                }
                userRoomCount = iPropertyAppUserRoomDao.batchSave(rowsList);
            }
        }

        //保存App用户项目信息
        AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
        appUserProjectPO.setProjectId(projectId);
        appUserProjectPO.setUserId(userId);
        //住户项目关系是否已存在。存在则做更新，否则做添加
        boolean userProjectIsExist = false;
        List<AppUserProjectPO> appUserProjectPOS = iPropertyAppUserProjectDao.getUserProject(appUserProjectPO);
        if (appUserProjectPOS != null && appUserProjectPOS.size() > 0) {
            appUserProjectPO = appUserProjectPOS.get(0);
            if (appUserProjectPO.getDataSource() != null && appUserProjectPO.getDataSource() == 1){
                appUserProjectPO.setDataSource(2);
            }
            userProjectIsExist = true;
        }
        appUserProjectPO = this.getAppUserProject(appUserGetUserInfoDTO, appUserProjectPO);
        appUserProjectPO.setUserLabel(appUserGetUserInfoDTO.getUserLabel());
        //住户可能已跟项目产生关系如在审核未通过中删除了
        Integer userProjectCount = 0;
        if (userProjectIsExist) {
            userProjectCount = iPropertyAppUserProjectDao.update(appUserProjectPO);
        } else {
            userProjectCount = iPropertyAppUserProjectDao.save(
                    (SqlUtil.durableData(appUserProjectPO, PlatformConstants.TABLE_SAVE)));
        }
        //项目开启了云对讲
        if (isSmartCommunity == ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType()) {
            ProjectSmartCommunityStatusChangeDTO projectSmartCommunityStatusChangeDTO = new ProjectSmartCommunityStatusChangeDTO();
            projectSmartCommunityStatusChangeDTO.setIsSmartCommunity(isSmartCommunity);
            projectSmartCommunityStatusChangeDTO.setProjectId(projectId);
            projectSmartCommunityStatusChangeDTO.setUserId(appUserInfoPO.getUserId());
            this.updateUserProjectSip(projectSmartCommunityStatusChangeDTO);
        }
        //返回有权限变更的用户Id
        return appUserInfoPO.getUserId();
    }

    /**
     * <desc>
     *      获取用户设备权限地址生产者
     * <desc/>
     *
     * @param dataJs  生产者发送的数据
     * @return
     * @author zhangs
     * @createDate 2018/02/25
     */
    private void userDeviceAuthAddressProducer(JSONObject dataJs) throws Exception {
        messageSender.send(RabbitMQConstant.RABBITMQ_USER_SAVE_DEVICE_AUTH_INFO_QUEUE,
                JSON.toJSONString(dataJs), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                RabbitMQConstant.RABBITMQ_USER_SAVE_DEVICE_AUTH_INFO_ROUTING_KEY);
    }

    /**
     * <desc>
     *      修改App用户信息接口
     * <desc/>
     *
     * @param appUserGetUserInfoDTO  App用户信息数据传输对象
     * @param loginUserId  物业登录账号
     * @param isSmartCommunity  是否使用云对讲： 0-否，1-是
     * @return List<String> 住户Id集
     * @author zhangs
     * @createDate 2017/09/26
     */
    @Override
//    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<String> updateAppUser(AppUserGetUserInfoDTO appUserGetUserInfoDTO, String loginUserId, Integer isSmartCommunity) throws Exception{
        List<String> userIds = new ArrayList<>();
        String projectId = appUserGetUserInfoDTO.getProjectId();

        //修改App用户信息以及相关信息操作
        List<Map<String, Object>> userIdLists = this.updateAppUserToDB(appUserGetUserInfoDTO, isSmartCommunity);
        if(userIdLists == null || userIdLists.size() == 0) {
            throw new DataAccessException("修改用户信息、用户房间信息以及用户项目信息有误");
        }

        //获取住户当前最新的有权限地址
        List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOS =
                iPropertyHouseHoldDeviceAuthService.getUserAuthAddr(userIdLists, projectId, loginUserId);
        UserDeviceAuthAddrAndSourceDTO userDeviceAuthAddrAndSourceDTO = new UserDeviceAuthAddrAndSourceDTO();
        userDeviceAuthAddrAndSourceDTO.setUserDeviceAuthAddreddDTOS(userDeviceAuthAddreddDTOS);
        userDeviceAuthAddrAndSourceDTO.setAuthSource(DeviceAuthEnum.DEVICEAUTH_PROPERTY.getType());
        //rabbitmq 发送任务
        //LOG.info("RabbitMQ_获取用户设备权限地址_生产者:" + JSON.toJSONString(userDeviceAuthAddrAndSourceDTO));
        JSONObject dataJs = new JSONObject();
        dataJs.put("data", JSONObject.toJSON(userDeviceAuthAddrAndSourceDTO));
        this.userDeviceAuthAddressProducer(dataJs);
        if (userIdLists != null && userIdLists.size() > 0) {
            for (Map<String, Object> param:userIdLists) {
                String userId = (String) param.get("userId");
                if (StringUtils.isNotBlank(userId)) {
                    userIds.add(userId);
                }
            }
        }
        //与旺龙一卡通对接-收集云端变动数据-住户信息
        this.prepareUserBasisInfoForSyncToSmartCard(projectId, userIds, SmartCardSyncDataOperTypeEnum.UPDATE);

        //推送云对讲指令
//        if (ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType() == isSmartCommunity) {
            //开启云对讲的项目需推送云对讲指令
        this.sendCloudIntercomOrder(SmartCommunityEnum.PUSH_USER_ROOM, projectId, userIds);
//        }
        for (Map<String, Object> map : userIdLists) {
            this.sendRoomOrder((Set<String>)map.get("allRoomIds"),projectId);
        }
        //推送平板增量数据
        List<Map<String,Object>> padDatas = iPropertyAppUserInfoDao.getUserRoomIdsByUserIdAndProjectId(
                StringHandlerUtil.splitString(appUserGetUserInfoDTO.getUserId()),projectId
        );
        //发送平板指令
        List<PadUserAuthPushDTO> dtos = new ArrayList<>();
        Map<String,Object> padMessage = new HashMap<>();
        for(Map<String,Object>  padData : padDatas){
            PadUserAuthPushDTO dto = new PadUserAuthPushDTO();
            dto.setProjectId(projectId);
            dto.setRoomId(padData.get("roomId").toString());
            dto.setUserId(padData.get("userId").toString());
            dto.setPushType(PadChangeBusinessEnum.PUSH_USER.getCommandType());
            //修改App用户信息接口
            dto.setInstructionType(15);
            dto.setSourceSystem(2);
            dtos.add(dto);
        }
        padMessage.put("data",JsonUtil.toJSON(dtos));
        messageSender.send(RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_QUEUE,
                JsonUtil.toJSON(padMessage), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_KEY);
        return userIds;
    }

    /**
     * <desc>
     *      修改App用户信息以及相关信息操作
     * <desc/>
     *
     * @param appUserGetUserInfoDTO  App用户信息数据传输对象
     * @param isSmartCommunity  是否使用云对讲： 0-否，1-是
     * @return List<Map<String, Object>> 住户Id集
     * @author zhangs
     * @createDate 2017/09/26
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<Map<String, Object>> updateAppUserToDB(AppUserGetUserInfoDTO appUserGetUserInfoDTO, Integer isSmartCommunity) throws Exception {
        String userId = appUserGetUserInfoDTO.getUserId();
        String projectId = appUserGetUserInfoDTO.getProjectId();

        //更新App用户信息
        Integer userInfoCount = 0;
        AppUserInfoPO appUserInfoPO = new AppUserInfoPO();
        appUserInfoPO.setUserId(userId);
        appUserInfoPO = iPropertyAppUserInfoDao.getOne(appUserInfoPO);
        appUserInfoPO.setUserId(appUserGetUserInfoDTO.getUserId());
        appUserInfoPO.setRealName(appUserGetUserInfoDTO.getRealName());
        appUserInfoPO.setPhoneNum(appUserGetUserInfoDTO.getPhoneNum());
        appUserInfoPO.setGender(appUserGetUserInfoDTO.getGender());
        appUserInfoPO.setUpdateTime(new Date());
        userInfoCount = iPropertyAppUserInfoDao.update(appUserInfoPO);

        //更新住户项目信息
        Integer userProjectCount = 0;
        AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
        appUserProjectPO.setProjectId(projectId);
        appUserProjectPO.setUserId(userId);
        appUserProjectPO.setStatus(DataStatusEnum.NORMAL.getType());
        List<AppUserProjectPO> appUserProjectPOS = iPropertyAppUserProjectDao.getUserProject(appUserProjectPO);
        appUserProjectPO = appUserProjectPOS.get(0);
        appUserProjectPO.setQqNum(appUserGetUserInfoDTO.getQqNum());
        appUserProjectPO.setIdCards(appUserGetUserInfoDTO.getIdCards());
        appUserProjectPO.setEmergencyContact(appUserGetUserInfoDTO.getEmergencyContact());
        appUserProjectPO.setEmergencyPhone(appUserGetUserInfoDTO.getEmergencyPhone());
        appUserProjectPO.setRemark(appUserGetUserInfoDTO.getRemark());
        appUserProjectPO.setUserLabel(appUserGetUserInfoDTO.getUserLabel());

        appUserProjectPO.setUpdateTime(new Date());
        if (appUserProjectPO.getUserType() == null) {
            appUserProjectPO.setUserType(AppUserProjectUserTypeEnum.USERPROJECT_USERTYPE_ORDINARY.getType());
        }
        userProjectCount = iPropertyAppUserProjectDao.update(appUserProjectPO);

        //项目开启了云对讲
        if (isSmartCommunity == ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType()) {
            ProjectSmartCommunityStatusChangeDTO projectSmartCommunityStatusChangeDTO = new ProjectSmartCommunityStatusChangeDTO();
            projectSmartCommunityStatusChangeDTO.setIsSmartCommunity(isSmartCommunity);
            projectSmartCommunityStatusChangeDTO.setProjectId(projectId);
            projectSmartCommunityStatusChangeDTO.setUserId(userId);
            this.updateUserProjectSip(projectSmartCommunityStatusChangeDTO);
        }

        //更新住户房间信息,无关的房屋信息归并到入住历史中
        //通过住户房间PO查询住户旧的房间信息
        AppUserRoomPO appUserRoomPO = new AppUserRoomPO();
        appUserRoomPO.setUserId(userId);
        appUserRoomPO.setProjectId(projectId);
        appUserRoomPO.setUserRoomStatus(AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        List<AppUserRoomPO> oldAppUserRooms = iPropertyAppUserRoomDao.getAllCompareListByPO(appUserRoomPO);
        //合并用户房间信息，返回有权限变更的用户Id(包含被影响的二级用户。Map<userId, userId>, Map<projectId, projectId>)
        List<Map<String, Object>> userIdLists = this.mergeAppUserRoom(appUserGetUserInfoDTO, oldAppUserRooms);

        if (userInfoCount <= 0 || userProjectCount <= 0 || (userIdLists == null || (userIdLists != null && userIdLists.size() <= 0))) {
            return null;
        } else {
            return userIdLists;
        }
    }

    /**
     * <desc>
     *      合并用户房间信息
     * <desc/>
     *
     * @param appUserGetUserInfoDTO  App用户信息数据传输对象
     * @param oldAppUserRooms 旧的用户房间信息List
     * @return Map<String, Object> 权限变更的用户Id集合
     * @author zhangs
     * @createDate 2017/09/26
     */
    private ArrayList<Map<String, Object>> mergeAppUserRoom(
            AppUserGetUserInfoDTO appUserGetUserInfoDTO,
            List<AppUserRoomPO> oldAppUserRooms) throws Exception {
        ArrayList<Map<String, Object>> userIdLists = new ArrayList<>();
        Map<String, Object> userIdSet = new HashMap<>();
        /**
         * 比较新旧地址中的roomId集。
         * 新旧地址中包含同一地址，对应用户房间信息做更新同时去除相应旧的中的roomId;
         * 旧的中不包含新地址时新的用户房间信息做插入操作;
         * oldRoomIds剩余需设置迁出。同时oldRoomIds是否为空即地址是否有变化标示是否需刷新权限
         */
        //获取旧的房间的roomId的Set
        Set<String> oldRoomIds = new HashSet<>();
        Set<String> allRoomIds = new HashSet<>();
        List<AppUserRoomPO> saveAppUserRoomPOS = new ArrayList<>();
        for(AppUserRoomPO appUserRoomPO:oldAppUserRooms) {
            oldRoomIds.add(appUserRoomPO.getRoomId());
            allRoomIds.add(appUserRoomPO.getRoomId());
        }
        String userId = appUserGetUserInfoDTO.getUserId();
        String projectId = appUserGetUserInfoDTO.getProjectId();
        userIdSet.put("userId", userId);
        userIdSet.put("projectId", projectId);
        userIdSet.put("allRoomIds", allRoomIds);
        userIdLists.add(userIdSet);
        List<AppUserRoomDTO> newAppUserRooms = appUserGetUserInfoDTO.getAppUserRoomDTOS();
        AppUserRoomPO appUserRoomPO = new AppUserRoomPO(userId, appUserGetUserInfoDTO.getProjectId(), appUserGetUserInfoDTO.getQqNum());

        //遍历新房间地址的同时与oldRoomIds比较
        if(StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(projectId)) {
            Map<String, Object> params;
            if((newAppUserRooms != null) && (newAppUserRooms.size() != 0)) {
                for(AppUserRoomDTO appUserRoomDTO:newAppUserRooms) {
                    if(oldRoomIds.contains(appUserRoomDTO.getRoomId())) {   //新旧相同做更新
                        params = new HashMap<>();
                        params.put("userId", userId);
                        params.put("projectId", projectId);
                        params.put("roomId", appUserRoomDTO.getRoomId());
                        params.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
//                        params.put("updateTime", new Date());
                        params.put("houserType", appUserRoomDTO.getHouserType());//更新
                        if (appUserRoomDTO.getHouserType() == 1) {//业主时重新赋值房间密码
                            Map<String, Object> params1 = new HashMap<>();
                            params1.put("projectId", projectId);
                            params1.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
                            params1.put("houserType", AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType());
                            params1.put("userId", userId);
                            params1.put("openPwd", "openPwdNotNull");
                            List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getExistHouserByRoom(params1);
                            if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
                                params.put("openPwd", appUserRoomPOS.get(0).getOpenPwd());
                            }
                        }
                        iPropertyAppUserRoomDao.updateUserByRoomId(params);

                        oldRoomIds.remove(appUserRoomDTO.getRoomId());
                    } else {    //新旧不同做插入
                        //获取重新赋值后的App用户房间实体对象
                        AppUserRoomPO userRoomPO = new AppUserRoomPO(userId, appUserGetUserInfoDTO.getProjectId(), appUserGetUserInfoDTO.getQqNum());
                        saveAppUserRoomPOS.add(this.getAppUserRoom(appUserRoomDTO, userRoomPO));
                    }
                }
                //保存新的用户房间信息
                if(saveAppUserRoomPOS.size() != 0) {
                    ArrayList<Map<String, Object>> rowList = new ArrayList<>();
                    Map<String, Object> oneRowMap;
                    for(AppUserRoomPO saveAppUserRoomPO:saveAppUserRoomPOS) {
                        oneRowMap = SqlUtil.durableData(saveAppUserRoomPO, PlatformConstants.TABLE_SAVE);
                        rowList.add(oneRowMap);
                    }
                    iPropertyAppUserRoomDao.batchSave(rowList);
                }
            }
            //oldRoomIds剩余需设置迁出。oldRoomIds是否为空即地址是否有变化-->是否需刷新权限
            if(oldRoomIds.size() != 0) {
                Iterator iterator = oldRoomIds.iterator();
                params = new HashMap<>();
                while(iterator.hasNext()) {
                    params.put("userId", userId);
                    params.put("projectId", projectId);
                    params.put("roomId", iterator.next());
                    params.put("updateTime", new Date());
                    params.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEOUT.getType());
                    iPropertyAppUserRoomDao.updateUserByRoomId(params);
                }

                //迁出的用户若为业主，该业主下的二级用户相关权限的处理:物理删除关系表
                for(AppUserRoomPO oldAppUserRoomPO:oldAppUserRooms) {
                    if(oldRoomIds.contains(oldAppUserRoomPO.getRoomId())) {
                        Integer houserType = oldAppUserRoomPO.getHouserType();
                        //业主用户迁出时会对对应房间下的用户有影响，迁入没有
                        if((AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType().equals(houserType))
                                && (AppUserRoomStatusEnum.USERROOM_STATUS_MOVEOUT.getType() == 2)) {
                            params = new HashMap<>();
                            params.put("parentUserId", userId);
                            params.put("projectId", projectId);
                            params.put("buildId", oldAppUserRoomPO.getBuildId());
                            params.put("unitId", oldAppUserRoomPO.getUnitId());
                            params.put("roomNum", oldAppUserRoomPO.getRoomNum());
                            //根据业主用户及地址查询用户授权关系
                            List<AppAuthRelationsPO> appAuthRelationsPOS =
                                    iPropertyAppAuthRelationsDao.getAppAuthRelationByMap(params);
                            if(appAuthRelationsPOS.size() != 0) {
                                AppAuthRelationsPO appAuthRelationsPO = appAuthRelationsPOS.get(0);
                                //删除一级住户与其对应二级授权人关系
                                iPropertyAppAuthRelationsDao.deleteById(String.valueOf(appAuthRelationsPO.getId()));
                                //删除二级住户与地址关系
                                Map<String, Object> delParams = new HashMap<>();
                                delParams.put("userId", appAuthRelationsPO.getUserId());
                                delParams.put("projectId", projectId);
                                delParams.put("buildId", oldAppUserRoomPO.getBuildId());
                                delParams.put("unitId", oldAppUserRoomPO.getUnitId());
                                delParams.put("roomNum", oldAppUserRoomPO .getRoomNum());
                                iPropertyAppUserRoomDao.delUserRoom(delParams);
                                userIdSet.put("userId", appAuthRelationsPO.getUserId());
                                userIdSet.put("projectId", appAuthRelationsPO.getProjectId());
                                userIdLists.add(userIdSet);
                            }
                        }
                    }
                }
            }
        }

        return userIdLists;
    }

    /**
     * <desc>
     *      从App用户信息数据传输对象获取App用户信息
     * </desc>
     *
     * @param appUserGetUserInfoDTO App用户信息数据传输对象
     * @return AppUserInfoPO App用户信息实体对象
     * @author zhangs
     * @createDate 2017/09/22
     */
    private AppUserInfoPO getAppUserInfo(AppUserGetUserInfoDTO appUserGetUserInfoDTO) throws Exception {
        AppUserInfoPO appUserInfoPO = new AppUserInfoPO();
//        BeanUtils.copyProperties(appUserGetUserInfoDTO, appUserInfoPO);
        appUserInfoPO.setUserId(appUserGetUserInfoDTO.getUserId());
        appUserInfoPO.setRealName(appUserGetUserInfoDTO.getRealName());
        appUserInfoPO.setPhoneNum(appUserGetUserInfoDTO.getPhoneNum());
        appUserInfoPO.setGender(appUserGetUserInfoDTO.getGender());
//        appUserInfoPO.setUserId(LogicIdUtil.userBusinessId());
        appUserInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
        Date createDate = new Date();
        appUserInfoPO.setCreateTime(createDate);
        appUserInfoPO.setUpdateTime(createDate);
        return appUserInfoPO;
    }

    /**
     * <desc>
     *      从App用户信息数据传输对象获取App用户项目信息
     * </desc>
     *
     * @param appUserGetUserInfoDTO App用户信息数据传输对象
     * @param appUserProjectPO App用户项目信息实体对象
     * @return AppUserProjectPO App用户项目信息实体对象
     * @author zhangs
     * @createDate 2017/09/22
     */
    private AppUserProjectPO getAppUserProject(AppUserGetUserInfoDTO appUserGetUserInfoDTO, AppUserProjectPO appUserProjectPO) throws Exception {
        if (StringUtils.isBlank(appUserProjectPO.getProjectType())) {
            appUserProjectPO.setProjectType(String.valueOf(AppUserProjectTypeEnum.USERPROJECT_TYPE_SELF.getType()));
        }
        if (StringUtils.isBlank(appUserProjectPO.getUserProjectStatus())) {
            appUserProjectPO.setUserProjectStatus(String.valueOf(AppUserProjectStatusEnum.USERPROJECT_USERPROJECTSTATUS_ENABLE.getType()));
        }
        appUserProjectPO.setQqNum(appUserGetUserInfoDTO.getQqNum());
        appUserProjectPO.setIdCards(appUserGetUserInfoDTO.getIdCards());
        appUserProjectPO.setEmergencyContact(appUserGetUserInfoDTO.getEmergencyContact());
        appUserProjectPO.setEmergencyPhone(appUserGetUserInfoDTO.getEmergencyPhone());
        appUserProjectPO.setRemark(appUserGetUserInfoDTO.getRemark());
        if (StringUtils.isEmpty(appUserProjectPO.getCardNum())) {
            appUserProjectPO.setCardNum("000000");
        }
//        appUserProjectPO.setQrCode();
        if (appUserProjectPO.getUserType() == null) {
            appUserProjectPO.setUserType(AppUserProjectUserTypeEnum.USERPROJECT_USERTYPE_ORDINARY.getType());
        }
        if (appUserProjectPO.getStatus() != DataStatusEnum.NORMAL.getType()) {
            appUserProjectPO.setStatus(DataStatusEnum.NORMAL.getType());
        }
        Date date = new Date();
        if (appUserProjectPO.getCreateTime() == null) {
            appUserProjectPO.setCreateTime(date);
        }
        appUserProjectPO.setUpdateTime(date);
        appUserProjectPO.setUserLabel(appUserGetUserInfoDTO.getUserLabel());
        return appUserProjectPO;
    }

    /**
     * <desc>
     *      从App用户信息数据传输对象获取App用户房间信息
     * </desc>
     *
     * @param appUserGetUserInfoDTO App用户信息数据传输对象
     * @return AppUserProjectPO App用户项目信息实体对象
     * @author zhangs
     * @createDate 2017/09/22
     */
    private List<AppUserRoomPO> getAppUserRoomList(AppUserGetUserInfoDTO appUserGetUserInfoDTO, String userId) throws Exception {
        List<AppUserRoomDTO> appUserRoomDTOS = appUserGetUserInfoDTO.getAppUserRoomDTOS();
        List<AppUserRoomPO> appUserRoomPOS = new ArrayList<>();

        if((appUserRoomDTOS != null) && (appUserRoomDTOS.size() != 0)) {
            for(AppUserRoomDTO appUserRoomDTO:appUserRoomDTOS) {
                AppUserRoomPO appUserRoomPO =
                        new AppUserRoomPO(userId, appUserGetUserInfoDTO.getProjectId(), appUserGetUserInfoDTO.getQqNum());
                //非业主住户需查出该房间已迁入业主设置的开门密码
                int houseType = appUserRoomDTO.getHouserType();
                if (AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType() != houseType) {
                    String roomId = appUserRoomDTO.getRoomId();
                    Map<String, Object> param = new HashMap<>();
                    param.put("roomId", roomId);
                    param.put("houserType", AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType());
                    param.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
                    param.put("status", DataStatusEnum.NORMAL.getType());
                    List<AppUserRoomPO> appUserRoomPOList = iPropertyAppUserRoomDao.getExistHouserByRoom(param);
                    if (appUserRoomPOList != null && appUserRoomPOList.size() > 0) {
                        String openPwd = appUserRoomPOList.get(0).getOpenPwd();
                        if (StringUtils.isNotEmpty(openPwd)) {
                            appUserRoomPO.setOpenPwd(openPwd);
                        }
                    }
                }
                appUserRoomPOS.add(this.getAppUserRoom(appUserRoomDTO, appUserRoomPO));
            }
        }

        return appUserRoomPOS;
    }

    /**
     * <desc>
     *      获取重新赋值后的App用户房间实体对象
     * </desc>
     *
     * @param appUserRoomDTO App用户房间信息数据传输对象
     * @param appUserRoomPO App用户房间信息实体对象
     * @return AppUserRoomPO App用户房间信息实体对象
     * @author zhangs
     * @createDate 2017/09/19
     */
    private AppUserRoomPO getAppUserRoom(AppUserRoomDTO appUserRoomDTO, AppUserRoomPO appUserRoomPO) {
        String projectId = appUserRoomPO.getProjectId();
        appUserRoomPO.setBuildId(appUserRoomDTO.getBuildId());
        appUserRoomPO.setUnitId(appUserRoomDTO.getUnitId());
        appUserRoomPO.setRoomId(appUserRoomDTO.getRoomId());
        appUserRoomPO.setRoomNum(appUserRoomDTO.getRoomNum());
        appUserRoomPO.setHouserType(appUserRoomDTO.getHouserType());
//        BeanUtils.copyProperties(appUserRoomDTO, appUserRoomPO)
        appUserRoomPO.setStatus(DataStatusEnum.NORMAL.getType());
        appUserRoomPO.setUserRoomStatus(AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        if(StringUtils.isNotBlank(projectId)) {
            appUserRoomPO.setProjectId(projectId);
        }
        appUserRoomPO.setSource(AppUserRoomSourceEnum.USERROOM_SOURCE_ADD.getType());
        Date date = new Date();
        appUserRoomPO.setCreateTime(date);
        appUserRoomPO.setUpdateTime(date);
        return appUserRoomPO;
    }


    /**
     * <desc>
     *      更新App用户信息
     * </desc>
     *
     * @param appUserInfoPO App用户信息实体对象
     * @return Integer 影响的数据数量
     * @author zhangs
     * @createDate 2017/09/19
     */
    @Override
    public Integer updateUser(AppUserInfoPO appUserInfoPO) throws Exception {
        return null;
    }

    /**
     * <desc>
     *      根据id删除用户
     * <desc/>
     *
     * @param userId App用户Id
     * @return Integer
     * @author zhangs
     * @createDate 2017/09/18
     */
    @Override
    public Integer delete(String userId) throws Exception{
        return null;
    }

    /**
     * <desc>
     *      根据用户房间实体对象更新迁入迁出状态
     * <desc/>
     *
     * @param appUserUpdateUserRoomStatusDTO   App用户房间状态信息数据传输对象
     * @param isSmartCommunity 是否使用云对讲： 0-否，1-是
     * @param authUserId 授权人Id
     * @param sceneType 推送场景类型(HouseHoldJPushSceneTypeEnum)
     * @return List<String> 住户Id集
     * @author zhangs
     * @createDate 2017/09/18
     */
    @Override
//    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<String> userRemove(
            AppUserUpdateUserRoomStatusDTO appUserUpdateUserRoomStatusDTO,
            Integer isSmartCommunity,
            String authUserId,
            String sceneType) throws Exception{
        Map<String,Object> auth = this.getOldUserTempAuth(authUserId, appUserUpdateUserRoomStatusDTO.getProjectId());
        List<Map<String,Object>> oldAllDoorAuthList =  iPropertyAppUserInfoDao.getOldAllDoorAuthList(
                appUserUpdateUserRoomStatusDTO.getProjectId(),
                appUserUpdateUserRoomStatusDTO.getAppUsersRemoveDTOList().get(0).getUserId());
        List<Map<String,Object>> oldAllElevatorAuthList =  iPropertyAppUserInfoDao.oldAllElevatorAuthList(
                appUserUpdateUserRoomStatusDTO.getProjectId(),
                appUserUpdateUserRoomStatusDTO.getAppUsersRemoveDTOList().get(0).getUserId());
        List<AppElevatorAuthDTO> elevatorFloorAuthList =  iPropertyAppUserInfoDao.getPushFloorAuth(
                 appUserUpdateUserRoomStatusDTO.getAppUsersRemoveDTOList().get(0).getUserId(),appUserUpdateUserRoomStatusDTO.getProjectId());
        List<Map<String,Object>> oldAllTalkAuthList =  iPropertyAppUserInfoDao.oldAllTalkAuthList(
                appUserUpdateUserRoomStatusDTO.getProjectId(),
                appUserUpdateUserRoomStatusDTO.getAppUsersRemoveDTOList().get(0).getUserId());
        //权限变更的用户Id集合
        List<String> userIds = new ArrayList<>();
        //迁出住户的用户房间状态信息数据传输对象集,用于去除迁出住户时删除迁出地址对应设备的一卡通权限
        List<AppUsersRemoveDTO> appUsersRemoveDTOList = new ArrayList<>();
        //用户拥有权限的地址以及用户信息、设备权限来源标识临时数据传输对象
        UserDeviceAuthAddrAndSourceDTO userDeviceAuthAddrAndSourceDTO = new UserDeviceAuthAddrAndSourceDTO();
        //获取住户当前最新的有权限地址
        List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOList = new ArrayList<>();

        //记录 需要清除 有被邀请权限的二级用户(在清除二级住户权限时会判断住户是否有自己的房间地址，若有则需要额外删除
        // 由父级用户赋予的设备权限；若无则直接清除二级用户所有的设备权限)
        //Map(userId,AppUserDelInvitedAuthDTO);  userId:二级用户Id
        Map<String, AppUserDelInvitedAuthDTO> delInvitedAuthDTOMap = new HashMap<>();

        //App用户房间状态信息数据传输对象
        List<AppUsersRemoveDTO> appUsersMoveDTOS = appUserUpdateUserRoomStatusDTO.getAppUsersRemoveDTOList();
        String projectId = appUserUpdateUserRoomStatusDTO.getProjectId();

        //保存住户入住历史
        List<AppUserStayInHistoryPO> appUserStayInHistoryPOS = new ArrayList<>();
        //云对讲指令推送业务指令参数JSONArray
        JSONArray jsonArray = new JSONArray();
        //遍历获取单个用户
        for(AppUsersRemoveDTO appUsersRemoveDTO:appUsersMoveDTOS) {
            //权限变更的用户Id和项目Id集合
            List<Map<String, Object>> userIdLists = new ArrayList<>();
            String userId = appUsersRemoveDTO.getUserId();
            Integer userRoomStatus = appUsersRemoveDTO.getUserRoomStatus();
            List<AppUserRoomDTO> appUserRoomDTOS = appUsersRemoveDTO.getAppUserRoomDTOS();
            if (AppUserRoomStatusEnum.USERROOM_STATUS_MOVEOUT.getType() == userRoomStatus) {
                //迁出
                appUsersRemoveDTOList.add(appUsersRemoveDTO);
            } else if (AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType() == userRoomStatus) {
                //住户由迁出状态再迁入，维护住户项目数据状态(只做更新)
                boolean result = this.updateUserProjectDataStatus(userId, projectId);
                //住户项目数据状态更新操作
                if (result) {
                    // 项目开启了云对讲
                    if (isSmartCommunity == ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType()) {
                        ProjectSmartCommunityStatusChangeDTO projectSmartCommunityStatusChangeDTO = new ProjectSmartCommunityStatusChangeDTO();
                        projectSmartCommunityStatusChangeDTO.setProjectId(projectId);
                        projectSmartCommunityStatusChangeDTO.setIsSmartCommunity(isSmartCommunity);
                        projectSmartCommunityStatusChangeDTO.setUserId(userId);
                        this.updateUserProjectSip(projectSmartCommunityStatusChangeDTO);
                    }
                } else {
                    break;
//                    throw new DataAccessException("维护由迁出到迁入状态时的住户项目数据状态有误");
                }
            }

            //用于极光推送，记录每个用户对应的房间号
            StringBuffer roomNumBuffer = new StringBuffer();

            //遍历获取用户所拥有的房间集合
            for(AppUserRoomDTO appUserRoomDTO:appUserRoomDTOS) {
                AppUserRoomPO appUserRoomPO = new AppUserRoomPO();
                String roomId = appUserRoomDTO.getRoomId();
                appUserRoomPO.setBuildId(appUserRoomDTO.getBuildId());
                appUserRoomPO.setUnitId(appUserRoomDTO.getUnitId());
                appUserRoomPO.setRoomId(appUserRoomDTO.getRoomId());
                appUserRoomPO.setRoomNum(appUserRoomDTO.getRoomNum());
                appUserRoomPO.setHouserType(appUserRoomDTO.getHouserType());
//                BeanUtils.copyProperties(appUserRoomDTO, appUserRoomPO)
                appUserRoomPO.setProjectId(projectId);
                appUserRoomPO.setUserId(userId);
//                appUserRoomPO.setStatus(DataStatusEnum.NORMAL.getType());
                Date date = new Date();
                appUserRoomPO.setUpdateTime(date);

                roomNumBuffer.append(appUserRoomDTO.getRoomNum()).append(",");

                //若迁入/迁出住户为业主，则清空该房间中非业主住户的开门密码且将该住户其他业主房间中已设置过的开门密码复制过来;
                // 不是业主且是迁入则获取该房间下业主设置的开门密码
                Map<String, Object> params;
                Integer houserType = appUserRoomPO.getHouserType();
                if (AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType().equals(houserType)) {
                    //清空该房间中非业主住户的开门密码
                    this.emptyOperPwdByRoom(projectId, roomId);

                    //将该住户其他业主房间中已设置过的开门密码复制过来
                    params = new HashMap<>();
                    params.put("projectId", projectId);
                    params.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
                    params.put("houserType", AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType());
                    params.put("userId", userId);
                    params.put("openPwd", "openPwdNotNull");
                    List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getExistHouserByRoom(params);
                    if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
                        appUserRoomPO.setOpenPwd(appUserRoomPOS.get(0).getOpenPwd());
                    }
                    //迁出的用户若为业主，该业主下的二级用户相关处理:逻辑删除用户关系，住户房间信息置为已迁出
                    if(AppUserRoomStatusEnum.USERROOM_STATUS_MOVEOUT.getType() == userRoomStatus) {
                        params = new HashMap<>();
                        params.put("parentUserId", userId);
                        params.put("projectId", projectId);
                        params.put("buildId", appUserRoomPO.getBuildId());
                        params.put("unitId", appUserRoomPO.getUnitId());
                        params.put("roomNum", appUserRoomPO.getRoomNum());
                        List<AppAuthRelationsPO> appAuthRelationsPOS = iPropertyAppAuthRelationsDao.getAppAuthRelationByMap(params);
                        if(appAuthRelationsPOS.size() != 0) {
                            for (AppAuthRelationsPO appAuthRelationsPO:appAuthRelationsPOS) {
                                //逻辑删除用户关系
                                this.deleteAuthRelationById(String.valueOf(appAuthRelationsPO.getId()));

                                String secondUserId = appAuthRelationsPO.getUserId();
                                //记录 需要清除 有被邀请权限的二级用户
                                AppUserDelInvitedAuthDTO appUserDelInvitedAuthDTO =
                                        new AppUserDelInvitedAuthDTO(secondUserId,userId);
                                delInvitedAuthDTOMap.put(secondUserId,appUserDelInvitedAuthDTO);
                                //住户房间信息置为已迁出
                                AppUserRoomPO appUserRoom = new AppUserRoomPO();
                                appUserRoom.setUserRoomStatus(AppUserRoomStatusEnum.USERROOM_STATUS_MOVEOUT.getType());
                                appUserRoom.setUserId(secondUserId);
                                appUserRoom.setProjectId(projectId);
                                appUserRoom.setBuildId(appUserRoomPO.getBuildId());
                                appUserRoom.setUnitId(appUserRoomPO.getUnitId());
                                appUserRoom.setRoomNum(appUserRoomPO.getRoomNum());
                                appUserRoom.setUpdateTime(new Date());
                                this.updateUserRoomStatusToDB(appUserRoom);
                                //若被影响住户(业主邀请下的二级用户)无已入住/待审核/未通过等三种状态房间则住户项目关系逻辑删除
                                Map<String, Object> param = new HashMap<>();
                                param.put("userId", secondUserId);
                                param.put("projectId", projectId);
                                param.put("notAudit", USERROOM_STATUS_AUDIT.getType());
                                param.put("moveIn", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
                                param.put("notPass", AppUserRoomStatusEnum.USERROOM_STATUS_NOTAUDIT.getType());
                                appUserRoomPOS = iPropertyAppUserRoomDao.getUserRoomByNotRemove(param);
                                if (appUserRoomPOS == null || appUserRoomPOS.size() < 1) {
                                    AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
                                    appUserProjectPO.setUserId(secondUserId);
                                    appUserProjectPO.setProjectId(projectId);
                                    appUserProjectPO = iPropertyAppUserProjectDao.getHouseHoldProject(appUserProjectPO).get(0);
                                    Integer status = appUserProjectPO.getStatus();
                                    if (status != DataStatusEnum.DELETE.getType()) {
//                                        appUserProjectPO.setStatus(DataStatusEnum.DELETE.getType());
                                        appUserProjectPO.setUpdateTime(new Date());
                                        this.updateSecondUserProjectToDB(appUserProjectPO);
                                    }
                                }
                                //收集地址变动受影响的住户
                                Map<String, Object> userIdSet = new HashMap<>();
                                userIdSet.put("userId", secondUserId);
                                userIdSet.put("projectId", projectId);
                                userIdLists.add(userIdSet);
                                userIds.add(secondUserId);

                                //保存住户入住历史
                                AppUserStayInHistoryPO appUserStayInHistoryPO = new AppUserStayInHistoryPO(secondUserId,
                                        projectId, appUserRoomPO.getBuildId(), appUserRoomPO.getUnitId(), appUserRoomPO.getRoomId(),
                                        appUserRoomPO.getRoomNum(), userRoomStatus);
                                appUserStayInHistoryPOS.add(appUserStayInHistoryPO);

                                //保存云对讲推送信息
                                JSONObject json = new JSONObject();
                                json.put("userId", secondUserId);
                                json.put("roomId", appUserRoomPO.getRoomId());
                                jsonArray.add(json);
                            }
                        }
                    }
                } else {
                    /*TODO 20180226议定：被邀请的住户在物业后台迁出后，二级用户与业主的用户关系数据清除(逻辑删除)，
                    在物业后台将该二级用户再次迁入该房间时恢复或创建二级用户与该房间当前业主的用户关系数据
                    (该房间业主可能在二级用户被迁出期间发生改变)*/

                    //不是业主且是迁入则获取该房间下业主设置的开门密码
                    if (AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType() == userRoomStatus) {
                        params = new HashMap<>();
                        params.put("roomId", roomId);
                        params.put("houserType", AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType());
                        params.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
                        List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getExistHouserByRoom(params);
                        if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
                            appUserRoomPO.setOpenPwd(appUserRoomPOS.get(0).getOpenPwd());
                        }
                        //非业主用户被迁入时，若已存在用户房间关系且来源为邀请，则恢复或创建二级用户与该房间当前业主的用户关系数据
                        this.mainTainUserRelationAtMoveIn(projectId, userId, roomId);
                    }

                    //不是业主且是迁出则需逻辑删除用户关系(AppAuthRelations)
                    if (AppUserRoomStatusEnum.USERROOM_STATUS_MOVEOUT.getType() == userRoomStatus) {
                        this.deleteAuthRelationByCondition(projectId, userId, roomId);
                    }
                }

                List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getUserRoomByPO(appUserRoomPO);
                appUserRoomPO.setUserRoomStatus(userRoomStatus);
                appUserRoomPO.setStatus(DataStatusEnum.NORMAL.getType());
                if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
                    this.updateUserRoomStatusToDB(appUserRoomPO);
                } else {
                    appUserRoomPO.setCreateTime(date);
                    appUserRoomPO.setSource(AppUserRoomSourceEnum.USERROOM_SOURCE_ADD.getType());
                    this.saveUserRoomStatusToDB(appUserRoomPO);
                }
                AppUserStayInHistoryPO appUserStayInHistoryPO = new AppUserStayInHistoryPO(userId, projectId,
                        appUserRoomDTO.getBuildId(), appUserRoomDTO.getUnitId(), appUserRoomDTO.getRoomId(),
                        appUserRoomDTO.getRoomNum(), userRoomStatus);
                appUserStayInHistoryPOS.add(appUserStayInHistoryPO);

                //保存云对讲推送信息
                JSONObject json = new JSONObject();
                json.put("userId", userId);
                json.put("roomId", appUserRoomDTO.getRoomId());
                jsonArray.add(json);
            }
            Map<String, Object> userIdSet = new HashMap<>();
            userIdSet.put("userId", userId);
            userIdSet.put("projectId", projectId);
            userIdLists.add(userIdSet);
            userIds.add(userId);

            //住户模块重构前此代码不可删，否则会因为主从同步问题，使下面的业务处理出现不可预估的错误
            Thread.sleep(2000);
            //获取住户(若住户为业主则含业主邀请的家人)当前最新的有权限地址
            List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOS =
                    iPropertyHouseHoldDeviceAuthService.getUserAuthAddr(userIdLists, projectId, authUserId);
            if (userDeviceAuthAddreddDTOS != null && userDeviceAuthAddreddDTOS.size() > 0) {
                for (UserDeviceAuthAddreddDTO userDeviceAuthAddreddDTO:userDeviceAuthAddreddDTOS) {
                    AppUserInfoPO appUserInfoPO = new AppUserInfoPO();
                    appUserInfoPO.setUserId(userId);
                    appUserInfoPO = iPropertyAppUserInfoDao.getOne(appUserInfoPO);
                    //未注册用户不需极光推送
                    if (appUserInfoPO != null && StringUtils.isNotEmpty(appUserInfoPO.getPassword())) {
                        userDeviceAuthAddreddDTO.setPhoneNum(appUserInfoPO.getPhoneNum());
                        //设置极光推送的消息
                        userDeviceAuthAddreddDTO.setJpushMsg(StringHandlerUtil.clearComma(roomNumBuffer).toString());
                    }
                }
            }
            //迁出所有地址需逻辑删除住户项目信息
            if (userDeviceAuthAddreddDTOS != null && userDeviceAuthAddreddDTOS.size() > 0) {
                userDeviceAuthAddreddDTOList.addAll(userDeviceAuthAddreddDTOS);
                //住户(若住户为业主则含业主邀请的家人)当前最新的有权限地址，若无地址则逻辑删除住户项目状态
                for (UserDeviceAuthAddreddDTO userDeviceAuthAddreddDTO:userDeviceAuthAddreddDTOS) {
                    Map<String, Object> userAuthRoomAddrMap = userDeviceAuthAddreddDTO.getUserAuthRoomAddrMap();
                    if (userAuthRoomAddrMap == null) {
                        AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
                        appUserProjectPO.setUserId(userDeviceAuthAddreddDTO.getUserId());
                        appUserProjectPO.setProjectId(projectId);
//                        appUserProjectPO.setStatus(DataStatusEnum.DELETE.getType());
                        appUserProjectPO.setUpdateDate(DateUtil.fomatDate(new Date()));
                        appUserProjectPO.setUserLabel("");
                        this.updateSecondUserProjectToDB(appUserProjectPO);
                        //清除独立门禁权限
//                        iPropertyUserInfoDao.deleteUserEntrance(userDeviceAuthAddreddDTO.getUserId(),projectId);

                        //房屋地址为空时会全清住户的设备权限，不需额外删除二级住户被邀请而赋予的权限
                        delInvitedAuthDTOMap.remove(userDeviceAuthAddreddDTO.getUserId());
                        //清除住户权限组权限
//                        iPropertyUserInfoDao.delEntranceAuth(authUserId,projectId);
                    }
                }
            }
            //迁入房间时需额外推送房间信息变更云对讲指令
            JSONArray pushRoom = new JSONArray();
            for (AppUserRoomDTO appUserRoomDTO:appUserRoomDTOS) {
                JSONObject json = new JSONObject();
                json.put("roomId", appUserRoomDTO.getRoomId());
                pushRoom.add(json);
            }
            //云对讲
            List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                    new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_ROOM, pushRoom.toJSONString(), projectId);
            changeLogPOS.add(deviceBusinessChangeLogPO);
            //云电梯
            DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                    = new DeviceBusinessElevatorChangeLogPO(projectId,
                    CloudElevatorChangeBusinessEnum.PUSH_ROOM_PWD,pushRoom.toJSONString());
            List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
            deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
            if (!changeLogPOS.isEmpty()) {
                JSONObject datajs = new JSONObject();
                datajs.put("data",changeLogPOS);
                this.smartCommunityOrdersProducer(datajs);
                datajs.put("data",deviceElevatorChangeLogPOS);
                this.cloudElevatorBusinessChangePush(datajs);
            }
            List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
            DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId,CloudEntranceChangeBusinessEnum.PUSH_ROOM_PWD, JsonUtil.toJSON(pushRoom));
            entranceChanges.add(entrancePO);
            // 发送云门禁指令
            JSONObject dataJs = new JSONObject();
            dataJs.put("data",entranceChanges);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(dataJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
            );
        }
        //保存住户入住历史
        this.saveUserStayInHistory(appUserStayInHistoryPOS);
        //发送平板指令
        List<PadUserAuthPushDTO> dtos = new ArrayList<>();
        Map<String,Object> padMessage = new HashMap<>();
        for(AppUserStayInHistoryPO history : appUserStayInHistoryPOS){
            PadUserAuthPushDTO dto = new PadUserAuthPushDTO();
            dto.setProjectId(history.getProjectId());
            dto.setRoomId(history.getRoomId());
            dto.setUserId(history.getUserId());
            dto.setPushType(PadChangeBusinessEnum.PUSH_USER.getCommandType());
            dto.setSourceSystem(appUserUpdateUserRoomStatusDTO.getSourceSystem());
            dto.setInstructionType(appUserUpdateUserRoomStatusDTO.getInstructionType());
            dtos.add(dto);
        }
        padMessage.put("data",JsonUtil.toJSON(dtos));
        messageSender.send(RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_QUEUE,
                JsonUtil.toJSON(padMessage), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_KEY);
        //迁出住户时去除迁出地址对应的一卡通设备权限
        if (appUsersRemoveDTOList.size() > 0) {
            appUserUpdateUserRoomStatusDTO = new AppUserUpdateUserRoomStatusDTO();
            appUserUpdateUserRoomStatusDTO.setAppUsersRemoveDTOList(appUsersRemoveDTOList);
            iPropertyHouseHoldDeviceAuthService.delUserOtherAuth(appUserUpdateUserRoomStatusDTO, projectId);
        }

        //住户地址变更刷新住户设备权限
        userDeviceAuthAddrAndSourceDTO.setUserDeviceAuthAddreddDTOS(userDeviceAuthAddreddDTOList);
        userDeviceAuthAddrAndSourceDTO.setAuthSource(DeviceAuthEnum.DEVICEAUTH_PROPERTY.getType());
        //住户权限变更需极光推送，推送场景类型
        userDeviceAuthAddrAndSourceDTO.setSceneType(sceneType);
        //需额外删除 被邀请而被赋予权限 的二级用户
        userDeviceAuthAddrAndSourceDTO.setDelInvitedAuthDTOMap(delInvitedAuthDTOMap);
        //rabbitmq 发送任务
        //LOG.info("RabbitMQ_获取用户设备权限地址_生产者:" + JSON.toJSONString(userDeviceAuthAddrAndSourceDTO));
        JSONObject dataJs = new JSONObject();
        dataJs.put("data", JSONObject.toJSON(userDeviceAuthAddrAndSourceDTO));
        this.userDeviceAuthAddressProducer(dataJs);
        if (sceneType.equals("2")) {//迁出时刷新app端授权的权限
            List<String> userIdList = iPropertyAppUserRoomDao.getAuthUserId(userIds.get(0),projectId);
            for (String userId : userIdList) {
                this.updateAppUserAuth(userIds,userId,projectId);
            }
        }

        //推送云对讲指令
        if (ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType() == isSmartCommunity) {
            //开启云对讲的项目需推送云对讲指令
//            this.sendCloudIntercomOrder(SmartCommunityEnum.PUSH_USER_ROOM, projectId, userIds);
            //由推送住户所有房间地址改为推送住户当前改变的房间地址
            List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                    new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_ROOM, jsonArray.toJSONString(), projectId);
            changeLogPOS.add(deviceBusinessChangeLogPO);
            if (!changeLogPOS.isEmpty()) {
                dataJs = new JSONObject();
                dataJs.put("data",changeLogPOS);

                this.smartCommunityOrdersProducer(dataJs);
            }
        }
        List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
        List<DeviceBusinessEntranceChangeLogPO> deviceEntranceChangeLogPOS = new ArrayList<>();
        //云电梯
        DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                = new DeviceBusinessElevatorChangeLogPO(projectId,
                CloudElevatorChangeBusinessEnum.PUSH_USER_ROOM,jsonArray.toJSONString());
        deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);

        // 云门禁
        DeviceBusinessEntranceChangeLogPO deviceBusinessEntranceChangeLogPO = new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_ROOM, jsonArray, projectId);
        deviceEntranceChangeLogPOS.add(deviceBusinessEntranceChangeLogPO);
        if (!deviceElevatorChangeLogPOS.isEmpty()) {
            dataJs.put("data", deviceElevatorChangeLogPOS);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(dataJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        }
        if (!deviceEntranceChangeLogPOS.isEmpty()) {
            dataJs.put("data", deviceEntranceChangeLogPOS);
            //发送云门禁指令
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(dataJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
            );
        }
        List<String> userIdList = new ArrayList<>();
        //查询该用户是否是注册过人脸的用户 如是则向c#端推送增量用户权限变更
        for(String userId : userIds){
            if(iPropertyAppUserRoomDao.isFaceUser(userId,projectId)>0){
                userIdList.add(userId);
            }
        }
        if(userIdList!=null && userIdList.size()>0 && iPropertyAppUserProjectDao.isStartFaceByProjectId(projectId)>0){
            //发送C#人脸识别用户权限变更增量推送指令,先进行持久化，再由定时任务统一去处理 只有设备禁用启用时deviceUnique才不为空
            SmartCardFaceTimePullInfoPO timePullInfoPO = new SmartCardFaceTimePullInfoPO();
            timePullInfoPO.setPullId(LogicIdUtil.bussinessId());
            timePullInfoPO.setProjectId(projectId);
            timePullInfoPO.setDeviceUniqueInfo("");
            timePullInfoPO.setSyncStatus(1);
            timePullInfoPO.setUserIdInfo(Joiner.on(",").join(userIdList));
            timePullInfoPO.setStatus(1);
            //由于权限更新需要一分钟，故此处为了保证权限最新故90秒后再进行定时任务下发增量数据
            timePullInfoPO.setAllowSyncTime(DateUtil.addSecond(new Date(), 310));
            timePullInfoPO.setCreateTime(new Date());
            iPropertyAppUserRoomDao.save(SqlUtil.durableData(timePullInfoPO,PlatformConstants.TABLE_SAVE));
        }
        //发送临时权限数据
        List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
        List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
        List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
        auth.put("userId", appUserUpdateUserRoomStatusDTO.getAppUsersRemoveDTOList().get(0).getUserId());
        auth.put("projectId", projectId);
        auth.put("type", 1);
        auth.put("doorAuthList",JsonUtil.toJSON(oldAllDoorAuthList));
        auth.put("elevatorAuthList",JsonUtil.toJSON(oldAllElevatorAuthList));
        auth.put("talkAuthList",JsonUtil.toJSON(oldAllTalkAuthList));
        auth.put("elevatorFloorAuthList",JsonUtil.toJSON(elevatorFloorAuthList));
        DeviceBusinessChangeLogPO po = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth), projectId);
        changes.add(po);
        DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId, CloudElevatorChangeBusinessEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth));
        elevatorChanges.add(elevatorPo);
        DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId, CloudEntranceChangeBusinessEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth));
        entranceChanges.add(entrancePO);
        JSONObject pushJs = new JSONObject();
        pushJs.put("data", changes);
        //发送云对讲业务指令
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE, JsonUtil.toJSON(pushJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE, RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
        pushJs.put("data", elevatorChanges);
        //推送云电梯业务指令
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                JsonUtil.toJSON(pushJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        //发送云门禁业务指令
        pushJs.put("data", entranceChanges);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                JSON.toJSONString(pushJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
        );
        return userIds;
    }

    /**
     * <desc>
     *      非业主用户被迁入时，若已存在用户房间关系且来源为邀请，则恢复或创建二级用户与该房间当前业主的用户关系数据
     * <desc/>
     *
     * @param projectId 项目Id
     * @param userId 用户Id
     * @param roomId 房间Id
     * @return Integer 被影响数据的数量
     * @author zhangs
     * @createDate 2018/02/27
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void mainTainUserRelationAtMoveIn(String projectId, String userId, String roomId) throws Exception {
        if (StringUtils.isBlank(projectId) || StringUtils.isBlank(userId) || StringUtils.isBlank(roomId)) {
            return;
        }
        AppUserRoomPO appUserRoomPO = new AppUserRoomPO();
        appUserRoomPO.setProjectId(projectId);
        appUserRoomPO.setUserId(userId);
        appUserRoomPO.setRoomId(roomId);
        List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getUserRoomByPO(appUserRoomPO);
        if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
            appUserRoomPO = appUserRoomPOS.get(0);
            Integer source = appUserRoomPO.getSource();
            if (source == AppUserRoomSourceEnum.USERROOM_SOURCE_INVITE.getType()) {
                Map<String, Object> params = new HashMap<>();
                params.put("userId", userId);
                params.put("projectId", projectId);
                params.put("roomId", roomId);
                List<AppAuthRelationsPO> appAuthRelationsPOS = iPropertyAppAuthRelationsDao.getAppAuthRelationByCondition(params);
                if (appAuthRelationsPOS != null && appAuthRelationsPOS.size() > 0) {
                    //恢复
                    AppAuthRelationsPO appAuthRelationsPO = appAuthRelationsPOS.get(0);
                    params.put("id", appAuthRelationsPO.getId());
                    params.put("status", DataStatusEnum.NORMAL.getType());
                    params.put("updateTime", new Date());
                    iPropertyAppAuthRelationsDao.updateAuthRelationsDataStatus(params);
                } else {
                    //新增
                    params = new HashMap<>();
                    params.put("projectId", projectId);
                    params.put("roomId", roomId);
                    params.put("houserType", AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType());
                    params.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
                    params.put("status", DataStatusEnum.NORMAL.getType());
                    appUserRoomPOS = iPropertyAppUserRoomDao.getExistHouserByRoom(params);
                    if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
                        appUserRoomPO = appUserRoomPOS.get(0);
                        AppAuthRelationsPO appAuthRelationsPO = new AppAuthRelationsPO();
                        appAuthRelationsPO.setUserId(userId);
                        appAuthRelationsPO.setParentUserId(appUserRoomPO.getUserId());
                        appAuthRelationsPO.setProjectId(projectId);
                        appAuthRelationsPO.setBuildId(appUserRoomPO.getBuildId());
                        appAuthRelationsPO.setUnitId(appUserRoomPO.getUnitId());
                        appAuthRelationsPO.setRoomId(appUserRoomPO.getRoomId());
                        appAuthRelationsPO.setRoomNum(appUserRoomPO.getRoomNum());
                        Date date = new Date();
                        appAuthRelationsPO.setCreateTime(date);
                        appAuthRelationsPO.setUpdateTime(date);
                        appAuthRelationsPO.setStatus(DataStatusEnum.NORMAL.getType());
                        iPropertyAppAuthRelationsDao.save(SqlUtil.durableData(appAuthRelationsPO, PlatformConstants.TABLE_SAVE));
                    }
                }

            }
        }
    }

    /**
     * <desc>
     *      清空房间中的开门密码
     * <desc/>
     *
     * @param projectId 项目Id
     * @param roomId 房间Id
     * @return Integer 被影响数据的数量
     * @author zhangs
     * @createDate 2018/02/25
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer emptyOperPwdByRoom(String projectId, String roomId) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("projectId", projectId);
        params.put("roomId", roomId);
        params.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        return iPropertyAppUserRoomDao.emptyOperPwdByRoom(params);
    }

    /**
     * <desc>
     *      根据数据Id逻辑删除用户关系
     * <desc/>
     *
     * @param id 数据Id
     * @return Integer 被影响数据的数量
     * @author zhangs
     * @createDate 2018/02/25
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer deleteAuthRelationById(String id) throws Exception {
        return iPropertyAppAuthRelationsDao.deleteById(id);
    }

    /**
     * <desc>
     *      根据条件逻辑删除用户关系
     * <desc/>
     *
     * @param projectId 项目Id
     * @param userId 用户Id
     * @param roomId 房间Id
     * @return Integer 被影响数据的数量
     * @author zhangs
     * @createDate 2018/02/25
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer deleteAuthRelationByCondition(String projectId, String userId, String roomId) throws Exception {
        Map<String, Object> param = new HashMap<>();
        param.put("projectId", projectId);
        param.put("userId", userId);
        param.put("roomId", roomId);
        return iPropertyAppAuthRelationsDao.deleteByMap(param);
    }

    /**
     * <desc>
     *      更新用户房间状态
     * <desc/>
     *
     * @param appUserRoom 用户房间信息实体类
     * @return Integer 被影响数据的数量
     * @author zhangs
     * @createDate 2018/02/25
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updateUserRoomStatusToDB(AppUserRoomPO appUserRoom) throws Exception {
        return iPropertyAppUserRoomDao.updateUserRoomStatus(appUserRoom);
    }

    /**
     * <desc>
     *      保存用户房间信息
     * <desc/>
     *
     * @param appUserRoom 用户房间信息实体类
     * @return Integer 被影响数据的数量
     * @author zhangs
     * @createDate 2018/02/25
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer saveUserRoomStatusToDB(AppUserRoomPO appUserRoom) throws Exception {
        return iPropertyAppUserRoomDao.save(SqlUtil.durableData(appUserRoom, PlatformConstants.TABLE_SAVE));
    }

    /**
     * <desc>
     *      更新用户项目信息
     * <desc/>
     *
     * @param appUserProjectPO 用户项目信息实体类
     * @return Integer 被影响数据的数量
     * @author zhangs
     * @createDate 2018/02/25
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updateSecondUserProjectToDB(AppUserProjectPO appUserProjectPO) throws Exception {
        return iPropertyAppUserProjectDao.update(appUserProjectPO);
    }

    /**
     * <desc>
     *      维护由迁出到迁入状态时的住户项目数据状态
     * <desc/>
     *
     * @param
     * @return
     * @author zhangs
     * @createDate 2018/02/25
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public boolean updateUserProjectDataStatus(String userId, String projectId) {
        AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
        appUserProjectPO.setUserId(userId);
        appUserProjectPO.setProjectId(projectId);
//                appUserProjectPO.setStatus(DataStatusEnum.DELETE.getType());
        //若有住户项目关系数据状态为删除的则更新数据状态
        List<AppUserProjectPO> appUserProjectPOS = iPropertyAppUserProjectDao.getHouseHoldProject(appUserProjectPO);
        if ((appUserProjectPOS != null) && (appUserProjectPOS.size() > 0)) {
            appUserProjectPO = appUserProjectPOS.get(0);
            //住户项目状态
            String userProjectStatus = appUserProjectPO.getUserProjectStatus();
            if (StringHandlerUtil.compareStrWithOutEmpty(userProjectStatus,
                    String.valueOf(AppUserProjectStatusEnum.USERPROJECT_USERPROJECTSTATUS_FROZEN.getType()))) {
                //重新由迁出到迁入，住户项目状态置为解冻
                appUserProjectPO.setUserProjectStatus(String.valueOf(AppUserProjectStatusEnum.
                        USERPROJECT_USERPROJECTSTATUS_ENABLE.getType()));
            }
        }
        appUserProjectPO.setUpdateTime(new Date());
        appUserProjectPO.setStatus(DataStatusEnum.NORMAL.getType());
        boolean result = iPropertyAppUserProjectDao.update(appUserProjectPO) > 0 ? true:false;
        return result;
    }

    /**
     * <desc>
     *      云对讲设备同步业务生产者
     * <desc/>
     *
     * @param dataJs  生产者发送的数据
     * @return
     * @author zhangs
     * @createDate 2018/02/25
     */
    private void smartCommunityOrdersProducer(JSONObject dataJs) throws Exception {
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
    }

    /**
     * <desc>
     *      云电梯设备同步业务生产者
     * <desc/>
     *
     * @param dataJs  生产者发送的数据
     * @return
     * @author zhangs
     * @createDate 2018/02/25
     */
    private void cloudElevatorBusinessChangePush(JSONObject dataJs) throws Exception {
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                JsonUtil.toJSON(dataJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
    }

    /**
     * <desc>
     *      审核用户接口
     * <desc/>
     *
     * @param examineHouseHoldDTO 审核住户数据传输对象
     * @param isSmartCommunity 是否使用云对讲： 0-否，1-是
     * @param projectId 项目Id
     * @param authUserId 授权人Id
     * @param sceneType 推送场景类型(HouseHoldJPushSceneTypeEnum)
     * @return
     * @author zhangs
     * @createDate 2017/09/21
     */
    @Override
//    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void examineUser(
            ExamineHouseHoldDTO examineHouseHoldDTO,
            Integer isSmartCommunity,
            String projectId,
            String authUserId,
            String sceneType) throws Exception {
        //用户拥有权限的地址以及用户信息、设备权限来源标识临时数据传输对象
        UserDeviceAuthAddrAndSourceDTO userDeviceAuthAddrAndSourceDTO = new UserDeviceAuthAddrAndSourceDTO();
        //获取住户当前最新的有权限地址
        List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOList = new ArrayList<>();
        //权限变更的用户Id集合(需审核通过)
        List<String> userIds = new ArrayList<>();

        String userId = examineHouseHoldDTO.getUserId();
        Integer userRoomStatus = examineHouseHoldDTO.getUserRoomStatus();

        //更新App用户信息
        Integer result = this.updateExamineUserToDB(userId, examineHouseHoldDTO);
        if (result <= 0) {
            throw new DataAccessException("更新审核用户时的用户信息有误");
        }
        //审核通过则需同步至一卡通以及与对讲
        if (userRoomStatus == AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType()) {
            userIds.add(userId);
        }

        //更新住户项目信息,更新审核用户时的用户房间信息以及保存住户入住历史
        //记录每个用户对应的房间号(用于极光推送)
        StringBuffer roomNumBuffer = this.updateUserProjectToDB(examineHouseHoldDTO, userRoomStatus, userId, projectId);
        if (roomNumBuffer.length() <= 0) {
            throw new DataAccessException("更新审核用户时的用户项目信息、用户房间信息有误");
        }
        //项目开启了云对讲且审核通过
        if ((isSmartCommunity == ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType()) &&
                (userRoomStatus == AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType())) {
            ProjectSmartCommunityStatusChangeDTO projectSmartCommunityStatusChangeDTO = new ProjectSmartCommunityStatusChangeDTO();
            projectSmartCommunityStatusChangeDTO.setIsSmartCommunity(isSmartCommunity);
            projectSmartCommunityStatusChangeDTO.setUserId(userId);
            projectSmartCommunityStatusChangeDTO.setProjectId(projectId);
            projectSmartCommunityStatusChangeDTO.setPhoneNum(examineHouseHoldDTO.getPhoneNum());
            this.updateUserProjectSip(projectSmartCommunityStatusChangeDTO);
        }

        //权限变更的用户Id和项目Id集合
        List<Map<String, Object>> userIdLists = new ArrayList<>();
        //收集地址变动受影响的住户
        Map<String, Object> userIdSet = new HashMap<>();
        userIdSet.put("userId", userId);
        userIdSet.put("projectId", projectId);
        userIdLists.add(userIdSet);


        //获取住户当前最新的有权限地址
        List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOS =
                iPropertyHouseHoldDeviceAuthService.getUserAuthAddr(userIdLists, projectId, authUserId);
        if (userDeviceAuthAddreddDTOS != null && userDeviceAuthAddreddDTOS.size() > 0) {
            AppUserInfoPO appUserInfoPO;
            for (UserDeviceAuthAddreddDTO userDeviceAuthAddreddDTO:userDeviceAuthAddreddDTOS) {
                appUserInfoPO = new AppUserInfoPO();
                appUserInfoPO.setUserId(userId);
                appUserInfoPO = iPropertyAppUserInfoDao.getOne(appUserInfoPO);
                //未注册用户不需极光推送
                if (appUserInfoPO != null && StringUtils.isNotEmpty(appUserInfoPO.getPassword())) {
                    userDeviceAuthAddreddDTO.setPhoneNum(appUserInfoPO.getPhoneNum());
                    //设置极光推送的消息
                    userDeviceAuthAddreddDTO.setJpushMsg(StringHandlerUtil.clearComma(roomNumBuffer).toString());
                }
            }
            userDeviceAuthAddreddDTOList.addAll(userDeviceAuthAddreddDTOS);
            LOG.info("【APP用户提交房屋自动认证】进入异步极光数据处理");
        }

        //住户地址变更刷新住户设备权限
        userDeviceAuthAddrAndSourceDTO.setUserDeviceAuthAddreddDTOS(userDeviceAuthAddreddDTOList);
        userDeviceAuthAddrAndSourceDTO.setAuthSource(DeviceAuthEnum.DEVICEAUTH_PROPERTY.getType());
        //住户权限变更需极光推送，推送场景类型
        userDeviceAuthAddrAndSourceDTO.setSceneType(sceneType);
        //rabbitmq 发送任务
        //LOG.info("RabbitMQ_获取用户设备权限地址_生产者:" + JSON.toJSONString(userDeviceAuthAddrAndSourceDTO));
        JSONObject dataJs = new JSONObject();
        dataJs.put("data", JSONObject.toJSON(userDeviceAuthAddrAndSourceDTO));
        this.userDeviceAuthAddressProducer(dataJs);
        LOG.info("【APP用户提交房屋自动认证】进入异步处理极光推送完成");

        //与旺龙一卡通对接-收集云端变动数据-住户信息
        if ((userRoomStatus == AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType() && (!userIds.isEmpty()))) {
            this.prepareUserBasisInfoForSyncToSmartCard(projectId, userIds, SmartCardSyncDataOperTypeEnum.ADD);
            //推送云对讲指令。开启云对讲且审核通过则推送
//            if ((ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType() == isSmartCommunity)){
                //开启云对讲的项目需推送云对讲指令
            this.sendCloudIntercomOrder(SmartCommunityEnum.PUSH_USER_ROOM, projectId, userIds);
//            }
        }
        //发送平板指令
        List<PadUserAuthPushDTO> dtos = new ArrayList<>();
        Map<String, Object> padMessage = new HashMap<>();
        if(examineHouseHoldDTO.getAppUserRoomDTOS()!=null && !examineHouseHoldDTO.getAppUserRoomDTOS().isEmpty()) {
            for(AppUserRoomDTO room : examineHouseHoldDTO.getAppUserRoomDTOS()) {
                PadUserAuthPushDTO dto = new PadUserAuthPushDTO();
                dto.setProjectId(projectId);
                dto.setRoomId(room.getRoomId());
                dto.setUserId(userId);
                dto.setPushType(PadChangeBusinessEnum.PUSH_USER.getCommandType());
                dto.setInstructionType(examineHouseHoldDTO.getInstructionType());
                dto.setSourceSystem(examineHouseHoldDTO.getSourceSystem());
                dtos.add(dto);
            }
        }
        padMessage.put("data", JsonUtil.toJSON(dtos));
        messageSender.send(RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_QUEUE,
                JsonUtil.toJSON(padMessage), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_KEY);
    }

    /**
     * <desc>
     *      更新审核用户时的用户信息
     * <desc/>
     *
     * @param userId 用户Id
     * @param examineHouseHoldDTO 审核住户数据传输对象
     * @return 被影响的数据数量
     * @author zhangs
     * @createDate 2018/02/26
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updateExamineUserToDB(String userId, ExamineHouseHoldDTO examineHouseHoldDTO) throws Exception {
        AppUserInfoPO appUserInfoPO = new AppUserInfoPO();
        appUserInfoPO.setUserId(userId);
        appUserInfoPO = iPropertyAppUserInfoDao.getOne(appUserInfoPO);
        appUserInfoPO.setUserId(examineHouseHoldDTO.getUserId());
        appUserInfoPO.setRealName(examineHouseHoldDTO.getRealName());
        appUserInfoPO.setPhoneNum(examineHouseHoldDTO.getPhoneNum());
        appUserInfoPO.setGender(examineHouseHoldDTO.getGender());
//        BeanUtils.copyProperties(examineHouseHoldDTO, appUserInfoPO)
        appUserInfoPO.setUpdateTime(new Date());
        return iPropertyAppUserInfoDao.update(appUserInfoPO);
    }

    /**
     * <desc>
     *      更新审核用户时的用户项目信息
     * <desc/>
     *
     * @param examineHouseHoldDTO 审核住户数据传输对象
     * @param userRoomStatus 用户房间关系状态
     * @param userId 用户Id
     * @param projectId 项目Id
     * @return StringBuffer 用户对应的房间号(英文逗号拼接)
     * @author zhangs
     * @createDate 2018/02/26
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public StringBuffer updateUserProjectToDB(
            ExamineHouseHoldDTO examineHouseHoldDTO,
            Integer userRoomStatus,
            String userId,
            String projectId) throws Exception{
        AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
        appUserProjectPO.setProjectId(projectId);
        appUserProjectPO.setUserId(userId);
        List<AppUserProjectPO> appUserProjectPOS = iPropertyAppUserProjectDao.getHouseHoldProject(appUserProjectPO);
        appUserProjectPO = appUserProjectPOS.get(0);
        appUserProjectPO.setQqNum(examineHouseHoldDTO.getQqNum());
        appUserProjectPO.setIdCards(examineHouseHoldDTO.getIdCards());
        appUserProjectPO.setEmergencyContact(examineHouseHoldDTO.getEmergencyContact());
        appUserProjectPO.setEmergencyPhone(examineHouseHoldDTO.getEmergencyPhone());
        appUserProjectPO.setRemark(examineHouseHoldDTO.getRemark());
//        BeanUtils.copyProperties(examineHouseHoldDTO, appUserProjectPO)
        appUserProjectPO.setUpdateTime(new Date());
        if (appUserProjectPO.getUserType() == null) {
            appUserProjectPO.setUserType(AppUserProjectUserTypeEnum.USERPROJECT_USERTYPE_ORDINARY.getType());
        }
        //更新住户房间状态(审核的均是业主房间)
        List<AppUserRoomDTO> appUserRoomDTOS = examineHouseHoldDTO.getAppUserRoomDTOS();
        //更新审核用户时的用户房间信息以及保存住户入住历史，记录每个用户对应的房间号(用于极光推送)
        StringBuffer roomNumBuffer = this.updateUserRoomAndSaveStayInHistoryToDB(appUserRoomDTOS, userRoomStatus, userId, projectId);
        if (roomNumBuffer.length() <= 0) {
            throw new DataAccessException("更新审核用户时的用户房间信息有误");
        }

        //操作的住户房间信息(状态为已入住/待审核)是否存在,存在则更新住户项目信息(正常)否则逻辑删除;审核通过则数据状态为正常
        Map<String, Object> param = new HashMap<>();
        param.put("userId", userId);
        param.put("projectId", projectId);
        param.put("notAudit", USERROOM_STATUS_AUDIT.getType());
        param.put("moveIn", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getUserRoomByNotRemove(param);
        if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
            appUserProjectPO.setStatus(DataStatusEnum.NORMAL.getType());
            //存在app授权认证添加的用户项目数据被审核通过，则将dataSource改为非1，使该用户在用户列表展示
            appUserProjectPO.setDataSource(2);
        } else {
            //用户无房间也不应删除
//            appUserProjectPO.setStatus(DataStatusEnum.DELETE.getType());
        }
        Integer result = iPropertyAppUserProjectDao.update(appUserProjectPO);
        LOG.info("【APP用户提交房屋自动认证】处理结束result"+result);
        if (result <= 0) {
            return new StringBuffer();
        }
        LOG.info("【APP用户提交房屋自动认证】roomNumBuffer"+roomNumBuffer);
        return roomNumBuffer;
    }

    /**
     * <desc>
     *      更新审核用户时的用户房间信息以及保存住户入住历史
     * <desc/>
     *
     * @param appUserRoomDTOS App用户房间信息数据传输对象集
     * @param userRoomStatus 用户房间关系状态
     * @param userId 用户Id
     * @param projectId 项目Id
     * @return StringBuffer 用户对应的房间号(英文逗号拼接)
     * @author zhangs
     * @createDate 2018/02/26
     */
    private StringBuffer updateUserRoomAndSaveStayInHistoryToDB(
            List<AppUserRoomDTO> appUserRoomDTOS,
            Integer userRoomStatus,
            String userId,
            String projectId) {
        //保存住户入住历史
        List<AppUserStayInHistoryPO> appUserStayInHistoryPOS = new ArrayList<>();
        //记录每个用户对应的房间号
        StringBuffer roomNumBuffer = new StringBuffer();

        //遍历获取用户所拥有的房间集合
        for(AppUserRoomDTO appUserRoomDTO:appUserRoomDTOS) {
            String roomId = appUserRoomDTO.getRoomId();
            Integer houseType = appUserRoomDTO.getHouserType();
            //若迁入住户为业主，则清空该房间中非业主住户的开门密码且将该住户其他业主房间中已设置过的开门密码复制过来
            String openPwd = null;
            if (userRoomStatus == AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType()) {
                //审核通过，保存住户入住历史
                AppUserStayInHistoryPO appUserStayInHistoryPO = new AppUserStayInHistoryPO(userId, projectId,
                        appUserRoomDTO.getBuildId(), appUserRoomDTO.getUnitId(), appUserRoomDTO.getRoomId(),
                        appUserRoomDTO.getRoomNum(), AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
                appUserStayInHistoryPOS.add(appUserStayInHistoryPO);

                if (houseType == AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType()) {
                    //则清空该房间中非业主住户的开门密码
                    Map<String, Object> params = new HashMap<>();
                    params.put("projectId", projectId);
                    params.put("roomId", roomId);
                    params.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
                    iPropertyAppUserRoomDao.emptyOperPwdByRoom(params);
                    //将该住户其他业主房间中已设置过的开门密码复制过来
                    params.put("houserType", AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType());
                    params.remove("roomId");
                    params.put("userId", userId);
                    params.put("openPwd", "openPwdNotNull");
                    List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getExistHouserByRoom(params);
                    if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
                        openPwd = appUserRoomPOS.get(0).getOpenPwd();
                    }
                }
            }
            AppUserRoomPO appUserRoomPO = new AppUserRoomPO();
            appUserRoomPO.setUserId(userId);
            appUserRoomPO.setRoomId(roomId);
            appUserRoomPO.setStatus(DataStatusEnum.NORMAL.getType());
            List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getUserRoomByPO(appUserRoomPO);
            appUserRoomPO = appUserRoomPOS.get(0);
            appUserRoomPO.setUserRoomStatus(userRoomStatus);
            appUserRoomPO.setUpdateTime(new Date());
            appUserRoomPO.setOpenPwd(openPwd);
            appUserRoomPO.setHouserType(houseType);
            Integer result = iPropertyAppUserRoomDao.updateUserRoomStatus(appUserRoomPO);
            if (result > 0) {
                roomNumBuffer.append(appUserRoomDTO.getRoomNum()).append(",");
            }
        }
        //存储住户的入住历史
        this.saveUserStayInHistory(appUserStayInHistoryPOS);
        return roomNumBuffer;
    }

    /**
     * <desc>
     *      冻结/解冻App用户状态接口
     * <desc/>
     *
     * @param appUserUpdateUserProjectStatusDTO 更新App用户项目状态数据传输对象
     * @return 被影响的数据数量
     * @author zhangs
     * @createDate 2017/09/29
     */
    @Override
//    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Integer userProjectStatus(AppUserUpdateUserProjectStatusDTO appUserUpdateUserProjectStatusDTO) throws Exception {
        Integer result = 0;
        if(appUserUpdateUserProjectStatusDTO == null) {
            return result;
        }
        String userIds = appUserUpdateUserProjectStatusDTO.getUserIds();
        if(StringUtils.isBlank(userIds)) {
            return result;
        }
        String[] userId = StringHandlerUtil.splitString(userIds);
        String projectId = appUserUpdateUserProjectStatusDTO.getProjectId();
        if(StringUtils.isBlank(projectId)) {
            return result;
        }
        String userProjectStatus = appUserUpdateUserProjectStatusDTO.getUserProjectStatus();
        if(StringUtils.isBlank(userProjectStatus)) {
            return result;
        }
        result = this.updateUserProjectToDB(userId, projectId, userProjectStatus);
        if (result <= 0) {
            throw new DataAccessException("冻结/解冻用户失败");
        }

        //推送云对讲指令
        Integer isSmartCommunity = appUserUpdateUserProjectStatusDTO.getIsSmartCommunity();
//        if (ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType() == isSmartCommunity) {
        //推送住户所有房间信息
        this.sendCloudIntercomOrder(SmartCommunityEnum.PUSH_USER_PROJECT, projectId, Arrays.asList(userId));
        //业主住户还需要单独推送业主身份的房间信息
        this.getHouseHoldRoomInfoToSendCloud(Arrays.asList(userId), projectId);
//        }
        String projectName = appUserUpdateUserProjectStatusDTO.getProjectName();
        //物业住户冻结/解冻需极光推送
        for (String user:userId) {
            //住户手机号
            AppUserInfoPO appUserInfoPO = new AppUserInfoPO();
            appUserInfoPO.setUserId(user);
            appUserInfoPO = iPropertyAppUserInfoDao.getOne(appUserInfoPO);
            String password = appUserInfoPO.getPassword();
            //未注册的用户不推送
            if (StringUtils.isEmpty(password)) {
                continue;
            }
            String phoneNum = appUserInfoPO.getPhoneNum();
            //推送指令
            Map<String,String> comands = new HashMap<>();
            comands.put("refreshSips", "1");
            //推送消息
            String msg = "您在{" + projectName + "}的住户权限已";
            if (StringHandlerUtil.compareStrWithOutEmpty(
                    String.valueOf(AppUserProjectStatusEnum.USERPROJECT_USERPROJECTSTATUS_ENABLE.getType()), userProjectStatus)) {
                //启用
                msg += "恢复...";
            } else {
                //冻结
                msg += "被冻结...";
            }
            List<HouseHoldManageJPushDTO> houseHoldManageJPushDTOS = new ArrayList<>();
            HouseHoldManageJPushDTO houseHoldManageJPushDTO = new HouseHoldManageJPushDTO();
            houseHoldManageJPushDTO.setMsg(msg);
            houseHoldManageJPushDTO.setPhoneNum(phoneNum);
            houseHoldManageJPushDTO.setProjectId(projectId);
            houseHoldManageJPushDTO.setComands(comands);
            houseHoldManageJPushDTOS.add(houseHoldManageJPushDTO);
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", JSONObject.toJSON(houseHoldManageJPushDTOS));
            messageSender.send(RabbitMQConstant.RABBITMQ_HOUSEHOLD_JPUSH_QUEUE,
                    JSON.toJSONString(dataJs), RabbitMQConstant.RABBITMQ_HOUSEHOLD_JPUSH_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_HOUSEHOLD_JPUSH_KEY);
            List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
            List<Map<String, Object>> rooms = iPropertyUserInfoDao.getUserRoomsInfos(user, projectId);
            List<Map<String,Object>> roomList=new ArrayList<>();
            //获取用户所属房间楼栋的云对讲设备及所有的围墙机
            if (!rooms.isEmpty()) {
                rooms.forEach(room -> {
                    String roomId = StringHandlerUtil.getNullOrStringForObject(room.get("roomId"));
                    if (StringUtils.isNotBlank(roomId)) {
                        String[] rd = StringHandlerUtil.splitString(roomId);
                        for (String r : rd) {
                            Map<String, Object> roomMap = new HashMap<>();
                            roomMap.put("roomId", r);
                            roomList.add(roomMap);
                        }
                    }
                });
            }
            DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId,CloudEntranceChangeBusinessEnum.PUSH_ROOM_PWD, JsonUtil.toJSON(roomList));
            entranceChanges.add(entrancePO);
            //发送云门禁指令
            dataJs.put("data",entranceChanges);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(dataJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY);
        }
        List<String> userIdsForSmartCard = Arrays.asList(userId);
        this.prepareUserBasisInfoForSyncToSmartCard(projectId, userIdsForSmartCard, SmartCardSyncDataOperTypeEnum.UPDATE);
        //推送平板增量数据
        List<Map<String,Object>> padDatas = iPropertyAppUserInfoDao.getUserRoomIdsByUserIdAndProjectId(
            StringHandlerUtil.splitString(appUserUpdateUserProjectStatusDTO.getUserIds()),projectId
        );
        //发送平板指令
        List<PadUserAuthPushDTO> dtos = new ArrayList<>();
        Map<String,Object> padMessage = new HashMap<>();
        for(Map<String,Object>  padData : padDatas){
            PadUserAuthPushDTO dto = new PadUserAuthPushDTO();
            dto.setProjectId(projectId);
            dto.setRoomId(padData.get("roomId").toString());
            dto.setUserId(padData.get("userId").toString());
            dto.setPushType(PadChangeBusinessEnum.PUSH_USER.getCommandType());
            dto.setInstructionType(appUserUpdateUserProjectStatusDTO.getInstructionType());
            dto.setSourceSystem(appUserUpdateUserProjectStatusDTO.getSourceSystem());
            dtos.add(dto);
            //向电梯推送房间的黑白名单
            List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
            Map<String,Object> blackList = new HashMap<>();
            blackList.put("projectId", projectId);
            blackList.put("roomId", padData.get("roomId").toString());
            blackList.put("version",0);
            DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId, CloudElevatorChangeBusinessEnum.PUSH_BLACK_LIST, JsonUtil.toJSON(blackList));
            elevatorChanges.add(elevatorPo);
            JSONObject pushJs = new JSONObject();
            pushJs.put("data", elevatorChanges);
            //推送云电梯业务指令
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(pushJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        }
        padMessage.put("data",JsonUtil.toJSON(dtos));
        messageSender.send(RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_QUEUE,
                JsonUtil.toJSON(padMessage), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_KEY);

        for(String u : userId) {
            //发送临时权限数据
            List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
            List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
            List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
            Map<String, Object> auth = new HashMap<>();
            auth.put("userId", u);
            auth.put("projectId", projectId);
            auth.put("type", 1);
            DeviceBusinessChangeLogPO po = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth), projectId);
            changes.add(po);
            DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId, CloudElevatorChangeBusinessEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth));
            elevatorChanges.add(elevatorPo);
            DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId, CloudEntranceChangeBusinessEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth));
            entranceChanges.add(entrancePO);
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changes);
            //发送云对讲业务指令
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE, JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE, RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
            dataJs.put("data", elevatorChanges);
            //推送云电梯业务指令
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(dataJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
            //发送云门禁业务指令
            dataJs.put("data", entranceChanges);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(dataJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
            );
        }
        return result;
    }

    /**
     * <desc>
     *      临时授权推送平板用户信息
     * </desc>
     *
     * @param projectId
     * @param userId
     * @author Jiaqi.X
     * @createDate 2019/03/25
     */
    public void pushPadUserInfos(String projectId,String userId,String doorAuth,String elevatorAuth,String talkAuth) throws Exception {
        //查询用户在当前项目下房间状态正常的房间id集合
        List<String> roomIds = iPropertyAppUserInfoDao.getRoomIdsByUserIdAndProjectId(userId,projectId);
        //发送平板指令
        List<PadUserAuthPushDTO> dtos = new ArrayList<>();
        Map<String,Object> padMessage = new HashMap<>();
        for(String roomId : roomIds){
            PadUserAuthPushDTO dto = new PadUserAuthPushDTO();
            dto.setProjectId(projectId);
            dto.setRoomId(roomId);
            dto.setUserId(userId);
            dto.setPushType(PadChangeBusinessEnum.PUSH_USER.getCommandType());
            dto.setSourceSystem(2);
            dto.setInstructionType(17);
            dtos.add(dto);

        }
        List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
        List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
        List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
        if(dtos.size() > 0) {
            padMessage.put("data", JsonUtil.toJSON(dtos));
            messageSender.send(RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_QUEUE,
                    JsonUtil.toJSON(padMessage), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_KEY);
        }
    }

    /**
     * <desc>
     *      推送临时权限至设备
     * </desc>
     *
     * @param projectId
     * @param userId
     * @param type 为1只推送云电梯指令  为2则只推送云门禁指令 为3则推送云电梯和云门禁指令
     * @author Jiaqi.X
     * @createDate 2019/03/25
     */
    public void pushTempUserInfos(String projectId,String userId,String doorAuth,String elevatorAuth,String talkAuth,String type) throws Exception {
        //发送临时权限数据
        List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
        List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
        List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
        Map<String,Object> auth = new HashMap<>();
        auth.put("userId",userId);
        auth.put("projectId",projectId);
        auth.put("type",1);
        auth.put("doorAuth",doorAuth);
        auth.put("elevatorAuth",elevatorAuth);
        auth.put("talkAuth",talkAuth);
        DeviceBusinessChangeLogPO po=new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth),projectId);
        changes.add(po);
        DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId,CloudElevatorChangeBusinessEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth));
        elevatorChanges.add(elevatorPo);
        DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId,CloudEntranceChangeBusinessEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth));
        entranceChanges.add(entrancePO);
        JSONObject dataJs = new JSONObject();
        dataJs.put("data",changes);
        //发送云对讲业务指令
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE, RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
        dataJs.put("data",elevatorChanges);
        //推送云电梯业务指令
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                JsonUtil.toJSON(dataJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        //发送云门禁业务指令
        dataJs.put("data",entranceChanges);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                JSON.toJSONString(dataJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
        );
    }

    /**
     * <desc>
     *      根据条件更新用户项目信息
     * <desc/>
     *
     * @param userIds 住户Id集
     * @param projectId 项目编号
     * @param userProjectStatus 用户项目状态
     * @return
     * @author zhangs
     * @createDate 2018/02/26
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updateUserProjectToDB(String[] userIds, String projectId, String userProjectStatus) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("userIds", userIds);
        params.put("projectId", projectId);
        params.put("userProjectStatus", userProjectStatus);
        params.put("updateTime", new Date());
        return iPropertyAppUserProjectDao.updateUserProjectStatus(params);
    }

    /**
     * <desc>
     *      业主住户需要单独推送业主身份的房间信息
     * <desc/>
     *
     * @param userIds 住户Id集
     * @param projectId 项目编号
     * @return
     * @author zhangs
     * @createDate 2018/01/09
     */
    private void getHouseHoldRoomInfoToSendCloud(List<String> userIds, String projectId) throws Exception {
        if (StringUtils.isBlank(projectId) || userIds == null || userIds.size() < 1) {
            return;
        }
        Map<String, Object> param = new HashMap<>();
        param.put("userIds", userIds);
        param.put("projectId", projectId);
        List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getHouseHoldRoomAtNormalStatus(param);
        if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
            JSONArray jsonArray = new JSONArray();
            for (AppUserRoomPO appUserRoomPO:appUserRoomPOS) {
                JSONObject json = new JSONObject();
                json.put("roomId", appUserRoomPO.getRoomId());
                jsonArray.add(json);
            }
            //推送住户所有业主身份房间信息
            //云对讲
            List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                    new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_ROOM, jsonArray.toJSONString(), projectId);
            changeLogPOS.add(deviceBusinessChangeLogPO);
            //云电梯
            DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                    = new DeviceBusinessElevatorChangeLogPO(projectId,
                    CloudElevatorChangeBusinessEnum.PUSH_ROOM_PWD,jsonArray.toJSONString());
            List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
            deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
            if (!changeLogPOS.isEmpty()) {
                JSONObject datajs = new JSONObject();
                //云对讲
                datajs.put("data", changeLogPOS);
                this.smartCommunityOrdersProducer(datajs);
                //云电梯
                datajs.put("data",deviceElevatorChangeLogPOS);
                this.cloudElevatorBusinessChangePush(datajs);
            }
        }
    }

    /**
     * <desc>
     *      删除用户房间关系(住户信息-未通过-删除)
     * <desc/>
     *
     * @param appUserDelUserRoomDTOS App用户房间信息数据传输对象集
     * @return Integer 被影响数据数量
     * @author zhangs
     * @createDate 2017/09/30
     */
    @Override
//    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer delUserRoom(List<AppUserDelUserRoomDTO> appUserDelUserRoomDTOS, String projectId) throws Exception {
        Integer delUserRoomCount = 0;
        if(appUserDelUserRoomDTOS.size() == 0) {
            return delUserRoomCount;
        }
        //根据用户房间信息进行删除
        delUserRoomCount = this.delUserRoomInfo(appUserDelUserRoomDTOS, projectId);

        return delUserRoomCount;
    }

    /**
     * <desc>
     *      删除用户房间关系(住户信息-未通过-删除)
     * <desc/>
     *
     * @param appUserDelUserRoomDTOS App用户房间信息数据传输对象集
     * @return Integer 被影响数据数量
     * @author zhangs
     * @createDate 2017/09/30
     */
    private Integer delUserRoomInfo(List<AppUserDelUserRoomDTO> appUserDelUserRoomDTOS, String projectId) throws Exception {
        Integer delUserRoomCount = 0;
        List<String> userIds = new ArrayList<>();
        //拼接条件并做数据库操作
        //逻辑删除住户跟房间的关系数据
        for(AppUserDelUserRoomDTO appUserDelUserRoomDTO:appUserDelUserRoomDTOS) {
            Map<String, Object> params = new HashMap<>();
            String userId = appUserDelUserRoomDTO.getUserId();
            Integer userRoomStatus = appUserDelUserRoomDTO.getUserRoomStatus();
            String buildId = appUserDelUserRoomDTO.getBuildId();
            String unitId = appUserDelUserRoomDTO.getUnitId();
            String roomId = appUserDelUserRoomDTO.getRoomId();
            String roomNum = appUserDelUserRoomDTO.getRoomNum();
            if(StringUtils.isNotBlank(userId) && userRoomStatus != null && StringUtils.isNotBlank(projectId)) {
                params.put("userId", userId);
                params.put("userRoomStatus", userRoomStatus);
                params.put("projectId", projectId);
                params.put("buildId", buildId);
                params.put("unitId", unitId);
                params.put("roomId", roomId);
                params.put("roomNum", roomNum);
                delUserRoomCount += iPropertyAppUserRoomDao.delUserRoom(params);
                userIds.add(userId);
            }

            //住户若没有已入住/待审核/未通过状态的房间，需将住户项目关系数据状态置为逻辑删除
            Map<String, Object> param = new HashMap<>();
            param.put("userId", userId);
            param.put("projectId", projectId);
            param.put("notAudit", USERROOM_STATUS_AUDIT.getType());
            param.put("moveIn", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
            param.put("notPass", AppUserRoomStatusEnum.USERROOM_STATUS_NOTAUDIT.getType());
            List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getUserRoomByNotRemove(param);
            if (appUserRoomPOS == null || appUserRoomPOS.size() < 1) {
                AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
                appUserProjectPO.setProjectId(projectId);
                appUserProjectPO.setUserId(userId);
                appUserProjectPO = iPropertyAppUserProjectDao.getHouseHoldProject(appUserProjectPO).get(0);
                Integer status = appUserProjectPO.getStatus();
                if (status != DataStatusEnum.DELETE.getType()) {
//                    appUserProjectPO.setStatus(DataStatusEnum.DELETE.getType());
                    appUserProjectPO.setUpdateTime(new Date());
                    iPropertyAppUserProjectDao.update(appUserProjectPO);
                }
            }
        }

        //推送云对讲指令
        this.sendCloudIntercomOrder(SmartCommunityEnum.PUSH_USER_ROOM, projectId, userIds);

        return delUserRoomCount;
    }

    /**
     * <desc>
     *      判断房间下是否已有业主
     * <desc/>
     *
     * @param appUserRoomOwnerIsExistDTO 房间中是否存在业主状态的数据传输对象
     * @return  List<AppUserRoomPO> 住户房间信息
     * @author zhangs
     * @createDate 2017/10/10
     */
    @Override
    public List<AppUserRoomPO> getExistHouserByRoom(@RequestBody AppUserRoomOwnerIsExistDTO appUserRoomOwnerIsExistDTO) {
        List<AppUserRoomPO> appUserRoomPOS = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        if(appUserRoomOwnerIsExistDTO == null) {
            return appUserRoomPOS;
        }
        String roomId = appUserRoomOwnerIsExistDTO.getRoomId();
        if(StringUtils.isBlank(roomId)) {
            return appUserRoomPOS;
        } else {
            params.put("roomId", roomId);
            params.put("checkUserId",appUserRoomOwnerIsExistDTO.getUserId());
        }
        params.put("houserType", AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType());
        params.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        params.put("status",1);
        appUserRoomPOS = iPropertyAppUserRoomDao.getExistHouserByRoom(params);
        return appUserRoomPOS;
    }

    /**
     * <desc>
     *      获取与用户绑定的地址
     * <desc/>
     *
     * @param appUserGetNotContactRoomDTO 未与用户绑定的地址信息数据传输对象
     * @return List<AppUserGetContractRoomDTO> 用户房间信息集
     * @author zhangs
     * @createDate 2017/10/20
     */
    @Override
    public List<AppUserGetContractRoomDTO> getRoomContactHouser(@RequestBody AppUserGetNotContactRoomDTO appUserGetNotContactRoomDTO) {
        List<AppUserGetContractRoomDTO> appUserGetContractRoomDTOS = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        if(appUserGetNotContactRoomDTO == null) {
            return appUserGetContractRoomDTOS;
        }
        String projectId = appUserGetNotContactRoomDTO.getProjectId();
        if(StringUtils.isNotBlank(projectId)) {
            params.put("projectId", projectId);
        }
        String buildId = appUserGetNotContactRoomDTO.getBuildId();
        if(StringUtils.isNotBlank(buildId)) {
            params.put("build", buildId);
        }
        String unitId = appUserGetNotContactRoomDTO.getUnitId();
        if(StringUtils.isBlank(unitId)) {
            return appUserGetContractRoomDTOS;
        }
        params.put("unitId", unitId);
        String userId = appUserGetNotContactRoomDTO.getUserId();
        if(StringUtils.isBlank(userId)) {
            return appUserGetContractRoomDTOS;
        }
        params.put("userId", userId);
        params.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        params.put("status", DataStatusEnum.NORMAL.getType());
        appUserGetContractRoomDTOS = iPropertyAppUserRoomDao.getRoomContactHouser(params);
        return appUserGetContractRoomDTOS;
    }

    /**
     * <desc>
     *      根据设备服务地址查询地址下住户现有权限地址
     * <desc/>
     *
     * @param params 楼栋列表或单元列表
     * @return List<UserDeviceAuthAddreddDTO> 住户现有权限地址集
     * @author zhangs
     * @createDate 2017/10/20
     */
    @Override
    public List<UserDeviceAuthAddreddDTO> getAuthAddrByDeviceAddr(@RequestBody Map<String, String> params) throws Exception{
        //List<String> buildIds = params.get("buildIds");
        String unitIds = params.get("unitIds");
        String projectId = params.get("projectId");
        if(StringUtils.isEmpty(unitIds) && StringUtils.isBlank(projectId)){
            return null;
        }
        String authUserId = params.get("authUserId");

        List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOList = new ArrayList<>();

        Map<String, Object> userIdSet;
        List<AppUserRoomPO> appUserRoomPOList;

        Map<String, Object> param = new HashMap<>();
        param.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        param.put("status", DataStatusEnum.NORMAL.getType());

        if (StringUtils.isNotEmpty(unitIds)) {
            param.put("unitIds", Arrays.asList(unitIds.split(",")));
        } else {
            param.put("projectId", projectId);
        }

        //根据设备服务地址查询地址下的住户
        appUserRoomPOList = iPropertyAppUserRoomDao.getUsersByAddr(param);

        List<Map<String, Object>> userIdLists = new ArrayList<>();
        if(appUserRoomPOList != null && appUserRoomPOList.size() > 0) {
            if (StringUtils.isBlank(projectId)) {
                projectId = appUserRoomPOList.get(0).getProjectId();
            }

            //遍历住户查询住户现有地址信息
            for(AppUserRoomPO appUserRoomPO:appUserRoomPOList) {
                userIdSet = new HashMap<>();
                userIdSet.put("projectId", projectId);
                userIdSet.put("userId", appUserRoomPO.getUserId());

                userIdLists.add(userIdSet);
            }
        }
        if (userIdLists.size() > 0) {
            //查询住户现有地址
            List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOS =
                    iPropertyHouseHoldDeviceAuthService.getUserAuthAddr(userIdLists, projectId, authUserId);
            if(userDeviceAuthAddreddDTOS != null && userDeviceAuthAddreddDTOS.size() > 0) {
                userDeviceAuthAddreddDTOList.addAll(userDeviceAuthAddreddDTOS);
            }
        }

        return userDeviceAuthAddreddDTOList;
    }

    /**
     * <desc>
     *      根据地址查询住户
     * <desc/>
     *
     * @param params 楼栋列表或单元列表
     * @return
     * @author zhangs
     * @createDate 2017/10/20
     */
    @Override
    public List<Map<String, Object>> getUserByAddr(@RequestBody Map<String, List<String>> params) throws Exception {
        List<Map<String, Object>> userIdLists = new ArrayList<>();
        List<String> buildIds = params.get("buildIds");
        List<String> unitIds = params.get("unitIds");
        List<String> loginUserIds = params.get("authUserId");
        if(loginUserIds == null || loginUserIds.isEmpty()) {
            return userIdLists;
        }
        Map<String, Object> userIdSet;
        List<AppUserRoomPO> appUserRoomPOList;

        Map<String, Object> param = new HashMap<>();
        param.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        param.put("status", DataStatusEnum.NORMAL.getType());
        param.put("buildIds", buildIds);
        param.put("unitIds", unitIds);

        appUserRoomPOList = iPropertyAppUserRoomDao.getUsersByAddr(param);

        if(appUserRoomPOList != null && appUserRoomPOList.size() > 0) {
            String projectId = appUserRoomPOList.get(0).getProjectId();
            for (AppUserRoomPO appUserRoomPO : appUserRoomPOList) {
                userIdSet = new HashMap<>();
                userIdSet.put("userId", appUserRoomPO.getUserId());
                userIdSet.put("projectId", projectId);

                userIdLists.add(userIdSet);
            }
        }
        return userIdLists;
    }

    /**
     * <desc>
     *      更新App端用户的设备权限
     * <desc/>
     *
     * @param userIds 二级用户Id
     * @param authUserId 一级用户Id
     * @param projectId 项目Id
     * @return
     * @author zhangs
     * @createDate 2017/10/20
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateAppUserAuth(List<String> userIds, String authUserId, String projectId) throws Exception{
        //LOG.info(String.format("【更新App端用户设备权限】:info{%s}, {%s}", userIds, projectId));
        if((userIds != null && !userIds.isEmpty()) && StringUtils.isNotBlank(projectId)) {
            Map<String, Object> userIdSet = new HashMap<>();    //用户Id集合。用于生成设备权限
            for(String userId:userIds) {
                userIdSet.put("userId", userId);
                userIdSet.put("projectId", projectId);
            }
            //包装用户Id和项目Id
            List<Map<String, Object>> userIdLists = new ArrayList<>();
            userIdLists.add(userIdSet);

            //获取住户当前最新的有权限地址用于刷新住户权限
            List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOS =
                    iPropertyHouseHoldDeviceAuthService.getUserAuthAddr(userIdLists, projectId, authUserId);
            UserDeviceAuthAddrAndSourceDTO userDeviceAuthAddrAndSourceDTO = new UserDeviceAuthAddrAndSourceDTO();
            userDeviceAuthAddrAndSourceDTO.setUserDeviceAuthAddreddDTOS(userDeviceAuthAddreddDTOS);
            userDeviceAuthAddrAndSourceDTO.setAuthSource(DeviceAuthEnum.DEVICEAUTH_APP.getType());
            //rabbitmq 发送任务
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", JSONObject.toJSON(userDeviceAuthAddrAndSourceDTO));
            this.userDeviceAuthAddressProducer(dataJs);
        }
    }

    /**
     * <desc>
     *      查询住户的手机号
     * <desc/>
     *
     * @param userId 住户ID
     * @return
     * @author zhangs
     * @createDate 2017/10/20
     */
    @Override
    public String getUserPhone(String userId) {
        AppUserInfoPO appUserInfoPO = new AppUserInfoPO(userId);
        appUserInfoPO = iPropertyAppUserInfoDao.getOne(appUserInfoPO);
        return appUserInfoPO.getPhoneNum();
    }

    /**
     * <desc>
     *      获取与用户绑定的楼栋下房间地址数量
     * <desc/>
     *
     * @param userId 住户Id
     * @param projectId 项目Id
     * @return Map<String, Integer> 楼栋Id与其对应住户房间数量的Map集，
     *      Map<buildId, roomCount>:楼栋Id，楼栋下住户绑定的房间数量
     * @author zhangs
     * @createDate 2017/11/10
     */
    @Override
    public Map<String,Integer> getBuildNotContactHouse(String userId, String projectId) {
        Map<String, Integer> resultMap = new HashMap<>();
        if(StringUtils.isBlank(userId) || StringUtils.isBlank(projectId)) {
            return resultMap;
        }
        //获取与用户绑定的楼栋下房间地址数量
        Map<String, Object> param = new HashMap<>();
        param.put("userId", userId);
        param.put("projectId", projectId);
        List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getRoomCountContactHouse(param);
        if(appUserRoomPOS.isEmpty()) {
            return resultMap;
        }
        //整理格式化数据
        String buildId = appUserRoomPOS.get(0).getBuildId();
        Integer resultCount = 0;
        for(int index = 0;index < appUserRoomPOS.size();index++) {
            if(StringHandlerUtil.compareStrWithOutEmpty(buildId, appUserRoomPOS.get(index).getBuildId())) {
                resultCount++;
            } else {
                resultMap.put(buildId, resultCount);
                buildId = appUserRoomPOS.get(index).getBuildId();
                resultCount = 1;
            }
            if(index == appUserRoomPOS.size() - 1) {
                resultMap.put(buildId, resultCount);
            }
        }
        return resultMap;
    }

    /**
     * <desc>
     *      获取与用户绑定的单元下房间地址数量
     * <desc/>
     *
     * @param userId 住户Id
     * @param projectId 项目Id
     * @param buildId 楼栋Id
     * @return Map<String, Integer> 单元Id与其对应住户房间数量的Map集，
     *      Map<unitId, roomCount>:单元Id，单元下住户绑定的房间数量
     * @author zhangs
     * @createDate 2017/11/10
     */
    @Override
    public Map<String, Integer> getUnitNotContactHouse(String userId, String projectId, String buildId) {
        Map<String, Integer> resultMap = new HashMap<>();
        if(StringUtils.isBlank(userId) || StringUtils.isBlank(projectId)) {
            return resultMap;
        }
        //获取与用户绑定的单元下房间地址数量
        Map<String, Object> param = new HashMap<>();
        param.put("userId", userId);
        param.put("projectId", projectId);
        param.put("buildId", buildId);
        List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getRoomCountContactHouse(param);
        if(appUserRoomPOS.isEmpty()) {
            return resultMap;
        }
        //整理格式化数据
        String unitId = appUserRoomPOS.get(0).getUnitId();
        Integer resultCount = 0;
        for(int index = 0;index < appUserRoomPOS.size();index++) {
            if(StringHandlerUtil.compareStrWithOutEmpty(unitId, appUserRoomPOS.get(index).getUnitId())) {
                resultCount++;
            } else {
                resultMap.put(unitId, resultCount);
                unitId = appUserRoomPOS.get(index).getUnitId();
                resultCount = 1;
            }
            if(index == appUserRoomPOS.size() - 1) {
                resultMap.put(unitId, resultCount);
            }
        }
        return resultMap;
    }


    /**
     * <desc>
     *      根据房间id查询住户列表
     * <desc/>
     *
     * @param roomId 房间id
     * @return Key值(userId,userName,qqNum,sipAccount,isAllowApp,isOnline,projectId)
     * @author Chunjian.G
     * @createDate 2017-11-16
     */
    @Override
    public List<Map<String, Object>> getUserByRoomId(String roomId) throws Exception {
        return iPropertyAppUserRoomDao.getUsersByRoomId(roomId);
    }

    /**
     * <desc>
     *      根据住户项目关系PO查询住户项目关系PO
     * <desc/>
     *
     * @param appUserProjectPO 住户项目关系PO
     * @return AppUserProjectPO 住户项目关系PO
     * @author zhangs
     * @createDate 2017-11-16
     */
    @RequestMapping(path = "manage/getUserProject",method = {RequestMethod.POST})
    @Override
    public AppUserProjectPO getUserProject(AppUserProjectPO appUserProjectPO) throws Exception {
        appUserProjectPO.setStatus(DataStatusEnum.NORMAL.getType());
        List<AppUserProjectPO> appUserProjectPOS = iPropertyAppUserProjectDao.getUserProject(appUserProjectPO);
        if (appUserProjectPOS != null && appUserProjectPOS.size() > 0) {
            return appUserProjectPOS.get(0);
        } else {
            return new AppUserProjectPO();
        }
    }



    /**
     * <desc>
     *      房屋管理-房屋详情-入住迁出记录
     * <desc/>
     *
     * @param checkHouseHoldByRoomDTO 房屋详情中查询入住迁出记录条件数据传输对象
     * @return List<CheckHouseHoldByRoomVO> 房屋详情中查询入住迁出记录数据信息
     * @author zhangs
     * @createDate 2017/11/23
     */
    @Override
    public List<CheckHouseHoldByRoomVO> moveInAndOutRecord(@RequestBody CheckHouseHoldByRoomDTO checkHouseHoldByRoomDTO) throws Exception {
        Map<String, Object> params = MapUtil.objectToMap(checkHouseHoldByRoomDTO, false);
        params.put("userRoomStatusMoveIn", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        params.put("userRoomStatusMoveOut", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEOUT.getType());
        return iPropertyAppUserRoomDao.getMoveInAndOutRecord(params);
    }

    /**
     * <desc>
     *      获取小区中所有住户项目信息
     * </desc>
     * @param projectId 项目Id
     * @return Integer 住户数量
     * @author zhangs
     * @createDate 2017/11/25
     */
    @Override
    public Integer getAllHouseProjectInfo(String projectId) throws Exception {
        if (StringUtils.isBlank(projectId)) {
            return 0;
        }
        Map<String, Object> param = new HashMap<>();
        param.put("projectId", projectId);
        param.put("status", DataStatusEnum.NORMAL.getType());
        param.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        return iPropertyAppUserProjectDao.getAllHouseProjectInfo(param);
    }

    /**
     * <desc>
     *      获取住户最新地址
     * </desc>
     * @param projectId 项目Id
     * @param userIds 住户Id集
     * @return List<AppUserProjectPO> 住户项目信息集
     * @author zhangs
     * @createDate 2017/11/25
     */
    @Override
    public List<AppUserRoomPO> getHouseHoldRoom(String projectId, List<String> userIds) throws Exception {
        List<AppUserRoomPO> appUserRoomPOS = new ArrayList<>();
        if (StringUtils.isBlank(projectId) || userIds == null || userIds.size() < 1) {
            return appUserRoomPOS;
        }
        for (String userId:userIds) {
            AppUserRoomPO appUserRoomPO = new AppUserRoomPO();
            appUserRoomPO.setProjectId(projectId);
            appUserRoomPO.setUserId(userId);
            appUserRoomPO.setUserRoomStatus(AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
            appUserRoomPO.setStatus(DataStatusEnum.NORMAL.getType());
            appUserRoomPOS.addAll(iPropertyAppUserRoomDao.getUserRoomByPO(appUserRoomPO));
        }
        return appUserRoomPOS;
    }

    /**
     * <desc>
     *      生成硬件推送指令并推送
     * </desc>
     * @param smartCommunityEnum 云对讲设备与云端同步业务数据指令枚举
     * @param projectId 项目Id
     * @param userIds 住户Id集
     * @return void
     * @author zhangs
     * @createDate 2017/11/25
     */
    private void sendCloudIntercomOrder(SmartCommunityEnum smartCommunityEnum, String projectId, List<String> userIds) throws Exception {
        //获取住户最新地址
        if (StringUtils.isBlank(projectId) || userIds == null || userIds.size() < 1) {
            return;
        }
        List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
        List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
        List<DeviceBusinessEntranceChangeLogPO> deviceEntranceChangeLogPOS = new ArrayList<>();
        if (smartCommunityEnum == SmartCommunityEnum.PUSH_USER_PROJECT) {
            //用户项目变更。SmartCommunityEnum中按单条推送
            for (String userId:userIds) {
                JSONObject json = new JSONObject();
                json.put("userId", userId);
                json.put("projectId", projectId);

                DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                        new DeviceBusinessChangeLogPO(smartCommunityEnum, json.toJSONString(), projectId);
                changeLogPOS.add(deviceBusinessChangeLogPO);

                //云电梯
                DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                        = new DeviceBusinessElevatorChangeLogPO(projectId,
                        CloudElevatorChangeBusinessEnum.PUSH_USER_PROJECT,json.toJSONString());
                deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);

                // 云门禁
                DeviceBusinessEntranceChangeLogPO deviceBusinessEntranceChangeLogPO = new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_PROJECT, json, projectId);
                deviceEntranceChangeLogPOS.add(deviceBusinessEntranceChangeLogPO);
            }
        } else {
            //用户房间变更。SmartCommunityEnum中按批量推送
            List<AppUserRoomPO> appUserRoomPOS = new ArrayList<>();
            for (String userId:userIds) {
                AppUserRoomPO appUserRoomPO = new AppUserRoomPO();
                appUserRoomPO.setProjectId(projectId);
                appUserRoomPO.setUserId(userId);
                appUserRoomPO.setUserRoomStatus(AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
                appUserRoomPOS.addAll(iPropertyAppUserRoomDao.getCompareListByPO(appUserRoomPO));
                appUserRoomPO.setUserRoomStatus(AppUserRoomStatusEnum.USERROOM_STATUS_MOVEOUT.getType());
                appUserRoomPOS.addAll(iPropertyAppUserRoomDao.getCompareListByPO(appUserRoomPO));
            }
            if (appUserRoomPOS.size() < 1) {
                return;
            }

            //业务指令参数JSONArray
            JSONArray jsonArray = new JSONArray();
            for (AppUserRoomPO appUserRoomPO:appUserRoomPOS) {
                String roomId = appUserRoomPO.getRoomId();
                String userId = appUserRoomPO.getUserId();
                JSONObject json = new JSONObject();
                json.put("userId", userId);
                json.put("roomId", roomId);
                jsonArray.add(json);
            }
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                    new DeviceBusinessChangeLogPO(smartCommunityEnum, jsonArray.toJSONString(), projectId);
            changeLogPOS.add(deviceBusinessChangeLogPO);

            //云电梯
            DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                    = new DeviceBusinessElevatorChangeLogPO(projectId,
                    CloudElevatorChangeBusinessEnum.PUSH_USER_ROOM,jsonArray.toJSONString());
            deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);

            // 云门禁
            DeviceBusinessEntranceChangeLogPO deviceBusinessEntranceChangeLogPO = new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_ROOM, jsonArray, projectId);
            deviceEntranceChangeLogPOS.add(deviceBusinessEntranceChangeLogPO);
        }
        if (!changeLogPOS.isEmpty()) {
            JSONObject datajs = new JSONObject();
            datajs.put("data", changeLogPOS);
            this.smartCommunityOrdersProducer(datajs);
        }
        if (!deviceElevatorChangeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", deviceElevatorChangeLogPOS);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(dataJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        }
        if (!deviceEntranceChangeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", deviceEntranceChangeLogPOS);
            //发送云门禁指令
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(dataJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
            );
        }
    }

    /**
     * <desc>
     *      生成房间硬件推送指令并推送
     * </desc>
     * @param set 房间
     * @param projectId 项目Id
     * @return void
     * @author Qiang.S
     * @createDate 2019/07/02
     */
    private void sendRoomOrder(Set<String> set, String projectId) throws Exception {
        if (set.size() > 0) {
            JSONArray pushRoom = new JSONArray();
            for(String roomId : set){
                if(!roomId.equals("projectId")) {
                    JSONObject j = new JSONObject();
                    j.put("roomId", roomId);
                    pushRoom.add(j);
                }
            }
            //云对讲
            List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                    new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_ROOM, pushRoom.toJSONString(), projectId);
            changeLogPOS.add(deviceBusinessChangeLogPO);
            JSONObject datajs = new JSONObject();
            datajs.put("data", changeLogPOS);
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JsonUtil.toJSON(datajs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
            //云电梯
            DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                    = new DeviceBusinessElevatorChangeLogPO(projectId,
                    CloudElevatorChangeBusinessEnum.PUSH_ROOM_PWD,pushRoom.toJSONString());
            List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
            deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
            datajs = new JSONObject();
            datajs.put("data", deviceElevatorChangeLogPOS);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(datajs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
            List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
            DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId, CloudEntranceChangeBusinessEnum.PUSH_ROOM_PWD, JsonUtil.toJSON(pushRoom));
            entranceChanges.add(entrancePO);
            // 发送云门禁指令
            JSONObject dataJs = new JSONObject();
            dataJs.put("data",entranceChanges);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(dataJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
            );
        }
    }

    /**
     * <desc>
     *      与旺龙一卡通对接-收集云端变动数据-住户基础信息
     * </desc>
     *
     * @param projectId 项目Id
     * @param userIds 住户信息集
     * @param dataOperType 操作类型。更新| 删除| 增加
     * @return void
     * @author zhangs
     * @createDate 2017/11/25
     */
    private void prepareUserBasisInfoForSyncToSmartCard(String projectId, List<String> userIds,
                                                        SmartCardSyncDataOperTypeEnum dataOperType) throws Exception {
        //有数据变动的用户信息集
       // String data = JSON.toJSONString(userIds);
        //推送数据给一卡通
        List<SmartCardSyncDataPullUserBasisInfoDTO> basisInfoDTOS = new ArrayList();

        for (String userId:userIds){
            List<SmartCardSyncDataPullUserBasisInfoDTO> basisInfoDTOList = iSmartCardUserInfoDao.getUserBasisInfo(projectId,userId);
            if ((null != basisInfoDTOList) && (!basisInfoDTOList.isEmpty())){
                basisInfoDTOS.add(basisInfoDTOList.get(0));
            } else {
                LOG.info(String.format("未能查询到用户：%s 在项目：%s中的信息",userId,projectId));
            }
        }
        if (basisInfoDTOS.isEmpty()){
            return;
        }
        //有数据变动的用户信息集
        String data = JSON.toJSONString(basisInfoDTOS);
        //打包
        SmartCardSyncDataPullDTO smartCardSyncDataPullDTO = new SmartCardSyncDataPullDTO(projectId, data,
                dataOperType, SmartCardSyncDataTypeEnum.USER_BASIS_DATA);
        //发送
        JSONObject dataJs = new JSONObject();
        dataJs.put("data",JSONObject.toJSON(smartCardSyncDataPullDTO));
        messageSender.send(RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_QUEUE,
                JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_ROUTING_KEY);
    }

    /**
     * <desc>
     *      项目云对讲由无到有，由禁用到启用需生成住户项目信息中的SIP信息
     * </desc>
     *
     * @param projectSmartCommunityStatusChangeDTO 项目云对讲启用状态变化DTO
     * @return void
     * @author zhangs
     * @createDate 2017/11/28
     */
    @Override
    public void updateUserProjectSip(ProjectSmartCommunityStatusChangeDTO projectSmartCommunityStatusChangeDTO) throws Exception {
        String projectId = projectSmartCommunityStatusChangeDTO.getProjectId();
        Integer isSmartCommunity = projectSmartCommunityStatusChangeDTO.getIsSmartCommunity();
        String userId = projectSmartCommunityStatusChangeDTO.getUserId();
        List<String> userIdList = new ArrayList<>();
        if (StringUtils.isBlank(projectId) || isSmartCommunity == null) {
            return;
        }
        if (isSmartCommunity == ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType()) {
            Map<String, Object> param = new HashMap<>();
            param.put("projectId", projectId);
            param.put("userId", userId);
            List<AppUserProjectUpdateDTO> appUserProjectUpdateDTOS = iPropertyAppUserProjectDao.getUserProjectSip(param);
            if (appUserProjectUpdateDTOS == null || appUserProjectUpdateDTOS.size() < 1) {
                return;
            }
            for (AppUserProjectUpdateDTO appUserProjectUpdateDTO:appUserProjectUpdateDTOS) {
                //新SIP信息生成规则：SipAccount：projectId + userId。SipPsd：由(userId+project)加密的32位小写MD5
                userId = appUserProjectUpdateDTO.getUserId();//新SIP账号生成规则
                String oldSipAccount = appUserProjectUpdateDTO.getSipAccount();

                //现将灵云快智userid作为sip账号
                String phoneNum;
                String newSipAccount = "";
                if(StringUtils.isEmpty(appUserProjectUpdateDTO.getPhoneNum())){
                    phoneNum = iPropertyAppUserInfoDao.getUserPhoneNumByUserId(userId);
                }else{
                    phoneNum = appUserProjectUpdateDTO.getPhoneNum();
                }
                Map<String,String> resultMap = iAppLykzCloudIntercomAccountService.getLykzCloudIntercomAccountByMoblie(phoneNum,"");
                if(resultMap==null){
                    CloudIntercomAccountInfoPO infoPO = iAppLykzCloudIntercomAccountService.createLykzCloudIntercomAccount(userId,phoneNum,"","");
                    if(infoPO!=null){
                        newSipAccount = infoPO.getClientUserId();
                    }
                }else{
                    newSipAccount = resultMap.get("lykzUserId");
                    //首先根据手机号查询cloud_intercom_account_info表中是否已有该用户灵云信息数据 没有则保存
                    if(iAppLykzCloudIntercomAccountService.getExistLykzInfo(resultMap.get("lykzUserId"))==0) {
                        CloudIntercomAccountInfoPO infoPO = new CloudIntercomAccountInfoPO();
                        String lykzId = LogicIdUtil.bussinessId();
                        infoPO.setCloudIntercomAccountId(lykzId);
                        infoPO.setAccountType(1);
                        infoPO.setAccount(resultMap.get("clientNumber"));
                        infoPO.setToken(resultMap.get("loginToken"));
                        infoPO.setClientPwd(resultMap.get("clientPwd"));
                        infoPO.setClientUserId(resultMap.get("lykzUserId"));
                        infoPO.setStatus(1);
                        infoPO.setCreateTime(new Date());
                        infoPO.setAppid(LYKZ_APPID);
                        Integer result = iAppUserLykzAccountDao.save(SqlUtil.durableData(infoPO, PlatformConstants.TABLE_SAVE));
                        if (result > 0) {
                            iAppUserLykzAccountDao.updateAppUserInfo(userId, lykzId);
                        }
                    }
                }

                String newSipPsd = Md5EncryptUtil.md5(userId + phoneNum).toLowerCase();
                //若SIP改变，则更新住户项目信息中的SIP，同时也删除原SIP相关信息,以及同步SIP信息
                if (!StringHandlerUtil.compareStrWithOutEmpty(newSipAccount, oldSipAccount)) {
                    //更新住户项目信息中的SIP
                    AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
                    appUserProjectPO.setUserId(appUserProjectUpdateDTO.getUserId());
                    appUserProjectPO.setProjectId(appUserProjectUpdateDTO.getProjectId());
                    appUserProjectPO.setProjectType(appUserProjectUpdateDTO.getProjectType());
                    appUserProjectPO.setCardNum(appUserProjectUpdateDTO.getCardNum());
                    appUserProjectPO.setUserProjectStatus(appUserProjectUpdateDTO.getUserProjectStatus());
                    appUserProjectPO.setSipAccount(appUserProjectUpdateDTO.getSipAccount());
                    appUserProjectPO.setSipPsd(appUserProjectUpdateDTO.getSipPsd());
                    appUserProjectPO.setQrCode(appUserProjectUpdateDTO.getQrCode());
                    appUserProjectPO.setQrCodeEndTime(appUserProjectUpdateDTO.getQrCodeEndTime());
                    appUserProjectPO.setIdCards(appUserProjectUpdateDTO.getIdCards());
                    appUserProjectPO.setQqNum(appUserProjectUpdateDTO.getQqNum());
                    appUserProjectPO.setTinyId(appUserProjectUpdateDTO.getTinyId());
                    appUserProjectPO.setEmergencyContact(appUserProjectUpdateDTO.getEmergencyContact());
                    appUserProjectPO.setEmergencyPhone(appUserProjectUpdateDTO.getEmergencyPhone());
                    appUserProjectPO.setIsAllowApp(appUserProjectUpdateDTO.getIsAllowApp());
                    appUserProjectPO.setIsAllowPhone(appUserProjectUpdateDTO.getIsAllowPhone());
                    appUserProjectPO.setUserType(appUserProjectUpdateDTO.getUserType());
                    appUserProjectPO.setRemark(appUserProjectUpdateDTO.getRemark());
                    appUserProjectPO.setStatus(appUserProjectUpdateDTO.getStatus());
                    appUserProjectPO.setCreateTime(appUserProjectUpdateDTO.getCreateTime());
                    appUserProjectPO.setUserLabel(appUserProjectPO.getUserLabel());
//                    BeanUtils.copyProperties(appUserProjectUpdateDTO, appUserProjectPO)
                    appUserProjectPO.setSipAccount(newSipAccount);
                    appUserProjectPO.setSipPsd(newSipPsd);
                    appUserProjectPO.setUpdateTime(new Date());
                    userIdList.add(appUserProjectUpdateDTO.getUserId());
                    this.updateSecondUserProjectToDB(appUserProjectPO);
                    //删除原SIP相关信息,并添加/更新SIP信息
                    this.cloudSipHandler(projectId,newSipAccount, newSipPsd, oldSipAccount);
                } else {
                    this.cloudSipHandler(projectId,newSipAccount, newSipPsd, null);
                }
            }

        }
    }

    /**
     * <desc>
     *      获取住户所在楼栋Id并以逗号拼接
     * <desc/>
     *
     * @param userId App用户Id
     * @param  projectId  项目Id
     * @return 住户所在楼栋Id并以逗号拼接
     * @author zhangs
     * @createDate 2017/11/23
     */
    @Override
    public String getBuildIdsByHouseHold(String userId, String projectId) throws Exception {
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(projectId)) {
            return "";
        }
        Map<String, Object> param = new HashMap<>();
        param.put("userId", userId);
        param.put("projectId", projectId);
        param.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        return iPropertyAppUserRoomDao.getBuildIdsByHouseHold(param);
    }

    /**
     * <desc>
     *      获取住户所在楼栋Id并以逗号拼接
     * <desc/>
     *
     * @param userId App用户Id
     * @param  projectId  项目Id
     * @return 住户所在楼栋
     * @author zhangs
     * @createDate 2017/11/23
     */
    @Override
    public List<Map<String,Object>> getUserBuilds(String userId, String projectId) throws Exception {
        return iPropertyAppUserRoomDao.getUserBuilds(userId,projectId);
    }

    /**
     * <desc>
     *      获取房间中正常状态住户的数量
     * <desc/>
     *
     * @param roomId 房间Id
     * @param  projectId  项目Id
     * @return 房间中正常状态住户的数量
     * @author zhangs
     * @createDate 2017/12/04
     */
    @Override
    public Integer getMoveInHouseHoldCount(String roomId, String projectId) throws Exception {
        AppUserRoomPO appUserRoomPO = new AppUserRoomPO();
        appUserRoomPO.setStatus(DataStatusEnum.NORMAL.getType());
        appUserRoomPO.setUserRoomStatus(AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        appUserRoomPO.setRoomId(roomId);
        appUserRoomPO.setProjectId(projectId);
        List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getUserRoomByPO(appUserRoomPO);
        if (appUserRoomPOS == null) {
            return 0;
        } else {
            return appUserRoomPOS.size();
        }
    }

    /**
     * <desc>
     *      获取房间中正常状态住户的数量
     * <desc/>
     *
     * @param roomId 房间Id
     * @param  projectId  项目Id
     * @return 房间中正常状态住户的数量
     * @author zhangs
     * @createDate 2017/12/04
     */
    @Override
    public Integer getUserMoveInHouseHoldCount(String roomId, String projectId,String userId) throws Exception {
        AppUserRoomPO appUserRoomPO = new AppUserRoomPO();
        appUserRoomPO.setStatus(DataStatusEnum.NORMAL.getType());
        appUserRoomPO.setUserRoomStatus(AppUserRoomStatusEnum.USERROOM_STATUS_MOVEIN.getType());
        appUserRoomPO.setRoomId(roomId);
        appUserRoomPO.setProjectId(projectId);
        appUserRoomPO.setUserId(userId);
        List<AppUserRoomPO> appUserRoomPOS = iPropertyAppUserRoomDao.getUserRoomByPO(appUserRoomPO);
        if (appUserRoomPOS == null) {
            return 0;
        } else {
            return appUserRoomPOS.size();
        }
    }

    /**
     * <desc>
     *      查询一卡通用户信息接口(一卡通用户+查询按钮)
     * <desc/>
     *
     * @param checkSmartCardUserDTO 查询App用户信息传输数据
     * @return Page<AppUserInfoGetVO> 用户房间信息分页集
     * @author zhangs
     * @createDate 2017/12/08
     */
    @Override
    public Page<AppUserInfoGetVO> getCheckSmartCardUserList(CheckSmartCardUserDTO checkSmartCardUserDTO) throws Exception {
        Page<AppUserInfoGetVO> page = new Page<>();
        String currentPage = checkSmartCardUserDTO.getCurrentPage();
        String pageSize = checkSmartCardUserDTO.getPageSize();
        page.getPage().setPageSize(pageSize);
        page.getPage().setCurrentPage(currentPage);

        Map<String, Object> params = MapUtil.objectToMap(checkSmartCardUserDTO, false);
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
//        params.put("status", DataStatusEnum.NORMAL.getType());
        params.put("smartCard", DeviceAuthEnum.DEVICEAUTH_SMARTCARD.getType());

        List<AppUserInfoGetVO> appUserInfoGetVOS = iPropertyAppUserRoomDao.getCheckSmartCardUserList(params);
        Integer pageCount = iPropertyAppUserRoomDao.getCheckSmartCardUserCount(params);
        page.setRows(appUserInfoGetVOS, pageCount);
        return page;
    }

    /**
     * <desc>
     *      修改一卡通用户信息
     * <desc/>
     *
     * @param  smartCardUserUpdateDTO 物业后台更新一卡通用户信息数据传输对象
     * @param  isSmartCommunity 是否开启云对讲
     * @return
     * @author zhangs
     * @createDate 2017/12/08
     */
    @Override
    public void updateSmartCardUser(SmartCardUserUpdateDTO smartCardUserUpdateDTO, Integer isSmartCommunity) throws Exception {
        String projectId = smartCardUserUpdateDTO.getProjectId();
        String userId = smartCardUserUpdateDTO.getUserId();

        //更新用户信息
        AppUserInfoPO appUserInfoPO = new AppUserInfoPO();
        appUserInfoPO.setUserId(userId);
        appUserInfoPO = iPropertyAppUserInfoDao.getOne(appUserInfoPO);
        String phoneNum = appUserInfoPO.getPhoneNum();
        String newPhoneNum = smartCardUserUpdateDTO.getPhoneNum();
        if (!StringHandlerUtil.compareStrWithOutEmpty(phoneNum, newPhoneNum)) {
            appUserInfoPO.setPhoneNum(newPhoneNum);
        }
        appUserInfoPO.setRealName(smartCardUserUpdateDTO.getRealName());
        appUserInfoPO.setUpdateTime(new Date());
        this.updateUserInfoToDB(appUserInfoPO);

        //项目开启了云对讲且审核通过
        if (isSmartCommunity == ProjectSmartCommunityStatusEnum.PROJECT_SMART_COMMUNITY_YES.getType()) {
            ProjectSmartCommunityStatusChangeDTO projectSmartCommunityStatusChangeDTO = new ProjectSmartCommunityStatusChangeDTO();
            projectSmartCommunityStatusChangeDTO.setProjectId(projectId);
            projectSmartCommunityStatusChangeDTO.setUserId(userId);
            projectSmartCommunityStatusChangeDTO.setIsSmartCommunity(isSmartCommunity);
            this.updateUserProjectSip(projectSmartCommunityStatusChangeDTO);
        }

        //与旺龙一卡通对接-收集云端变动数据-住户信息
        List<String> userIdsForSmartCard = new ArrayList<>();
        userIdsForSmartCard.add(userId);
        this.prepareUserBasisInfoForSyncToSmartCard(projectId, userIdsForSmartCard, SmartCardSyncDataOperTypeEnum.UPDATE);
    }

    /**
     * <desc>
     *      根据条件更新用户项目信息
     * <desc/>
     *
     * @param appUserInfoPO 住户Id集
     * @return Integer 被影响数据数量
     * @author zhangs
     * @createDate 2018/02/26
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer updateUserInfoToDB(AppUserInfoPO appUserInfoPO) throws Exception {
        return iPropertyAppUserInfoDao.update(appUserInfoPO);
    }

    /**
     * <desc>
     *      获取住户项目数据状态(status)正常下住户项目状态(userProjectStatus)
     * <desc/>
     *
     * @param  projectId 项目Id
     * @param  userId 用户Id
     * @return Integer
     * @author zhangs
     * @createDate 2017/12/21
     */
    @Override
    public Integer getUserProjectStatusAtNormal(String projectId, String userId) throws Exception {
        AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
        appUserProjectPO.setUserId(userId);
        appUserProjectPO.setProjectId(projectId);
        appUserProjectPO.setStatus(DataStatusEnum.NORMAL.getType());
        List<AppUserProjectPO> appUserProjectPOS = iPropertyAppUserProjectDao.getUserProject(appUserProjectPO);
        if (appUserProjectPOS != null && appUserProjectPOS.size() > 0) {
            appUserProjectPO = appUserProjectPOS.get(0);
            return Integer.parseInt(appUserProjectPO.getUserProjectStatus());
        }
        return AppUserProjectStatusEnum.USERPROJECT_USERPROJECTSTATUS_ENABLE.getType();
    }

    /**
     * <desc>
     *      查询项目下的用户是否存在
     * <desc/>
     *
     * @param  projectId 项目Id
     * @param  userId 用户Id
     * @return Integer
     * @author Juguang.S
     * @createDate 2021/06/18
     */
    @Override
    public Integer getUserIsExist(String projectId, String userId) throws Exception {
        AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
        appUserProjectPO.setUserId(userId);
        appUserProjectPO.setProjectId(projectId);
        appUserProjectPO.setStatus(DataStatusEnum.NORMAL.getType());
        List<AppUserProjectPO> appUserProjectPOS = iPropertyAppUserProjectDao.getUserProject(appUserProjectPO);
        if (appUserProjectPOS != null && appUserProjectPOS.size() > 0) {
            return 1;
        }else{
            return 0;
        }
    }

    /**
     * <desc>
     *      存储住户的入住历史(迁入/迁出)
     * <desc/>
     *
     * @param  appUserStayInHistoryPOS 住户迁入迁出历史记录实体类集
     * @return
     * @author zhangs
     * @createDate 2017/12/25
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void saveUserStayInHistory(List<AppUserStayInHistoryPO> appUserStayInHistoryPOS) {
        if (appUserStayInHistoryPOS == null || appUserStayInHistoryPOS.size() < 1) {
            return;
        }
        iPropertyAppUserStayInHistoryDao.saveUserStayInHistory(appUserStayInHistoryPOS);
    }

    /**
     * <desc>
     *      查询住户的入住历史(迁入/迁出)
     * <desc/>
     *
     * @param  projectId 项目Id
     * @param  userId 住户Id
     * @return List<AppUserStayInHistoryDTO> App用户详情页中入住历史数据传输对象集
     * @author zhangs
     * @createDate 2017/12/25
     */
    private List<AppUserStayInHistoryDTO> getUserStayInHistory(String projectId, String userId) {
        List<AppUserStayInHistoryDTO> appUserStayInHistoryDTOS = new ArrayList<>();
        if (StringUtils.isBlank(projectId) || StringUtils.isBlank(userId)) {
            return appUserStayInHistoryDTOS;
        }
        Map<String, Object> param = new HashMap<>();
        param.put("userId", userId);
        param.put("projectId", projectId);
        return iPropertyAppUserStayInHistoryDao.getUserStayInHistory(param);
    }


    /**
     * <desc>
     *      对sip数据源中的Sip账号进行添加，更新，或删除操作
     * <desc/>
     * @param  addOrUpdateUserName  根据userName添加或更新Sip数据源的数据（存在则更新，不存在则添加）
     * @param  addOrUpdatePassword  添加或更新Sip数据源的password
     * @param  delUserName  根据userName删除Sip数据源的数据
     * @author Biao.R
     * @createDate 2018/1/9
     */
    @Override
    public void cloudSipHandler(String projectId,String addOrUpdateUserName, String addOrUpdatePassword, String delUserName) throws Exception {
        PropertySubscriberHanlerDTO subscriberHanlerDTO = new PropertySubscriberHanlerDTO(projectId,addOrUpdateUserName, addOrUpdatePassword, delUserName);
        JSONObject js = new JSONObject();
        js.put("data",JSONObject.toJSON(subscriberHanlerDTO));
        messageSender.send(RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_QUEUE, JsonUtil.toJSON(js), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_KEY);
    }

    /**
     * <desc>
     *      临时提供一个通过手机号码查询APP用户id接口
     * </desc>
     *
     * @param phoneNum
     * @return
     * @author wangzhi
     * @createDate 2018-04-18
     */
    @Override
    public String getAppUserIdTemporary(String phoneNum) throws Exception {
        String userId = iPropertyAppUserInfoDao.getAppUserIdTemporary(phoneNum);
        return userId;
    }

    /**
     * <desc>
     *      更新人脸注册信息
     * <desc/>
     *
     * @param  appUserProjectPO 人脸注册信息
     * @return Integer
     * @author Qiang.S
     * @createDate 2018/05/18
     */
    @Override
    public Integer updatePreUserBaiduFaceInfo(AppUserProjectPO appUserProjectPO) throws Exception {
        return iPropertyUserInfoDao.updatePreUserBaiduFaceInfo(appUserProjectPO);
    }

    /**
     * <desc>
     *     查询此身份证是否已被绑定
     * </desc>
     *
     * @param userId 用户编号
     * @param projectId 项目编号
     * @param idcardKey 身份证序号
     * @return
     * @author Qiang.S
     * @createDate 2018-08-22
     */
    @Override
    public Integer getIDCardByUserId(String userId, String projectId, String idcardKey) throws Exception {
        return iPropertyUserInfoDao.getIDCardByUserId(userId,projectId,idcardKey);
    }

    /**
     * <desc>
     *     绑定身份证
     * </desc>
     *
     * @param userId 用户编号
     * @param projectId 项目编号
     * @param idcardKey 身份证序号
     * @param idCard 身份证号
     * @return
     * @author Qiang.S
     * @createDate 2018-08-22
     */
    @Override
    public Integer bindingIDCard(String userId, String projectId, String idcardKey,String idCard,String idCardStatus,boolean remark) throws Exception {

        String mark = "";
        if(StringUtils.isNotBlank(idCardStatus) && "1".equals(idCardStatus)){
            mark = "1";
            iPropertyUserInfoDao.updateIDCardInfo(userId,projectId,idcardKey,"1",idCard,mark);
        }else{
            iPropertyUserInfoDao.updateIDCardInfo(userId,projectId,idcardKey,"1",idCard,mark);
            new Thread(() -> {
                try{
                    if(remark){
                        Thread.sleep(6000);
                    }
                    //绑定身份证时如状态为冻结则无须推送指令于设备
                    List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
                    JSONObject json = new JSONObject();
                    json.put("userId", userId);
                    json.put("projectId", projectId);
                    DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                            new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_PROJECT, json,projectId);
                    changeLogPOS.add(deviceBusinessChangeLogPO);
                    JSONObject dataJs = new JSONObject();
                    dataJs.put("data",changeLogPOS);
                    messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                            JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                            RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

                    //云电梯
                    DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                            = new DeviceBusinessElevatorChangeLogPO(projectId,
                            CloudElevatorChangeBusinessEnum.PUSH_USER_PROJECT,json.toJSONString());
                    List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
                    deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
                    dataJs.put("data",deviceElevatorChangeLogPOS);
                    messageSender.send(
                            RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                            JsonUtil.toJSON(dataJs),
                            RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                            RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);

                    // 云门禁
                    List<DeviceBusinessEntranceChangeLogPO> changeEntranceLogPOS = new ArrayList<>();
                    changeEntranceLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_PROJECT, json, projectId));
                    dataJs.put("data", changeEntranceLogPOS);
                    //发送云门禁指令
                    messageSender.send(
                            RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                            JSON.toJSONString(dataJs),
                            RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                            RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
                    );
                    //发送临时权限数据
                    List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
                    List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
                    List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
                    Map<String,Object> auth = new HashMap<>();
                    auth.put("userId",userId);
                    auth.put("projectId",projectId);
                    auth.put("type",1);
                    DeviceBusinessChangeLogPO po=new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth),projectId);
                    changes.add(po);
                    DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId,CloudElevatorChangeBusinessEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth));
                    elevatorChanges.add(elevatorPo);
                    DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId,CloudEntranceChangeBusinessEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth));
                    entranceChanges.add(entrancePO);
                    JSONObject pushJs = new JSONObject();
                    pushJs.put("data",changes);
                    //发送云对讲业务指令
                    messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,JsonUtil.toJSON(pushJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE, RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
                    pushJs.put("data",elevatorChanges);
                    //推送云电梯业务指令
                    messageSender.send(
                            RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                            JsonUtil.toJSON(pushJs),
                            RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                            RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
                    //发送云门禁业务指令
                    pushJs.put("data",entranceChanges);
                    messageSender.send(
                            RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                            JSON.toJSONString(pushJs),
                            RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                            RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
                    );
                } catch (Exception e) {
                    throw new DataAccessException("【物业-住户管理】修改住户角色组推送平板指令失败", e);
                }
            }).start();
        }
        return 1;
    }

    /**
     * <desc>
     *     解绑身份证
     * </desc>
     *
     * @param userId 用户编号
     * @param projectId 项目编号
     * @return
     * @author Qiang.S
     * @createDate 2018-08-22
     */
    @Override
    public Integer untieIDCard(String userId, String projectId) throws Exception {
        iPropertyUserInfoDao.updateIDCardInfo(userId,projectId,"","0",null,"");
        List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
        JSONObject json = new JSONObject();
        json.put("userId", userId);
        json.put("projectId", projectId);
        DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_PROJECT, json,projectId);
        changeLogPOS.add(deviceBusinessChangeLogPO);
        JSONObject dataJs = new JSONObject();
        dataJs.put("data",changeLogPOS);
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

        //云电梯
        DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                = new DeviceBusinessElevatorChangeLogPO(projectId,
                CloudElevatorChangeBusinessEnum.PUSH_USER_PROJECT,json.toJSONString());
        List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
        deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
        dataJs.put("data",deviceElevatorChangeLogPOS);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                JsonUtil.toJSON(dataJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);

        // 云门禁
        List<DeviceBusinessEntranceChangeLogPO> changeEntranceLogPOS = new ArrayList<>();
        changeEntranceLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_PROJECT, json, projectId));
        dataJs.put("data", changeEntranceLogPOS);
        //发送云门禁指令
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                JSON.toJSONString(dataJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
        );
        //发送临时权限数据
        List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
        List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
        List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
        Map<String,Object> auth = new HashMap<>();
        auth.put("userId",userId);
        auth.put("projectId",projectId);
        auth.put("type",1);
        DeviceBusinessChangeLogPO po=new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth),projectId);
        changes.add(po);
        DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId,CloudElevatorChangeBusinessEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth));
        elevatorChanges.add(elevatorPo);
        DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId,CloudEntranceChangeBusinessEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth));
        entranceChanges.add(entrancePO);
        JSONObject pushJs = new JSONObject();
        pushJs.put("data",changes);
        //发送云对讲业务指令
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,JsonUtil.toJSON(pushJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE, RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
        pushJs.put("data",elevatorChanges);
        //推送云电梯业务指令
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                JsonUtil.toJSON(pushJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        //发送云门禁业务指令
        pushJs.put("data",entranceChanges);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                JSON.toJSONString(pushJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
        );
        return 1;
    }

    /**
     * <desc>
     *     身份证挂失信息更新
     * </desc>
     *
     * @param userId 用户编号
     * @param projectId 项目编号
     * @param isLoss 挂失状态:0 正常,1 挂失
     * @return
     * @author Qiang.S
     * @createDate 2019-02-20
     */
    @Override
    public Integer updateIsLossInfo(String userId, String projectId, String isLoss) throws Exception {
        List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
        JSONObject json = new JSONObject();
        json.put("userId", userId);
        json.put("projectId", projectId);
        DeviceBusinessChangeLogPO deviceBusinessChangeLogPO =
                new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_USER_PROJECT, json,projectId);
        changeLogPOS.add(deviceBusinessChangeLogPO);
        JSONObject dataJs = new JSONObject();
        dataJs.put("data",changeLogPOS);
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

        //云电梯
        DeviceBusinessElevatorChangeLogPO deviceBusinessElevatorChangeLogPO
                = new DeviceBusinessElevatorChangeLogPO(projectId,
                CloudElevatorChangeBusinessEnum.PUSH_USER_PROJECT,json.toJSONString());
        List<DeviceBusinessElevatorChangeLogPO> deviceElevatorChangeLogPOS = new ArrayList<>();
        deviceElevatorChangeLogPOS.add(deviceBusinessElevatorChangeLogPO);
        dataJs.put("data",deviceElevatorChangeLogPOS);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                JsonUtil.toJSON(dataJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);

        // 云门禁
        List<DeviceBusinessEntranceChangeLogPO> changeEntranceLogPOS = new ArrayList<>();
        changeEntranceLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_PROJECT, json, projectId));
        dataJs.put("data", changeEntranceLogPOS);
        //发送云门禁指令
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                JSON.toJSONString(dataJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
        );
        //发送临时权限数据
        List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
        List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
        List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
        Map<String,Object> auth = new HashMap<>();
        auth.put("userId",userId);
        auth.put("projectId",projectId);
        auth.put("type",1);
        DeviceBusinessChangeLogPO po=new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth),projectId);
        changes.add(po);
        DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId,CloudElevatorChangeBusinessEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth));
        elevatorChanges.add(elevatorPo);
        DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId,CloudEntranceChangeBusinessEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth));
        entranceChanges.add(entrancePO);
        JSONObject pushJs = new JSONObject();
        pushJs.put("data",changes);
        //发送云对讲业务指令
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,JsonUtil.toJSON(pushJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE, RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
        pushJs.put("data",elevatorChanges);
        //推送云电梯业务指令
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                JsonUtil.toJSON(pushJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        //发送云门禁业务指令
        pushJs.put("data",entranceChanges);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                JSON.toJSONString(pushJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
        );
        return iPropertyUserInfoDao.updateIsLossInfo(userId,projectId,isLoss);
    }

    /**
     * <desc>
     *      获取房间类型
     * <desc/>
     *
     * @param roomId 房间Id
     * @param  projectId  项目Id
     * @return 房间类型
     * @author Juguang.S
     * @createDate 2019/08/14
     */
    public Integer getHousesType(String roomId,String projectId) throws Exception{

        return iPropertyUserInfoDao.getHousesType(roomId,projectId);
    }

    /**
     * <desc>
     *      修改用户信息
     * <desc/>
     *
     * @param dto
     * @return 房间类型
     * @author Qiang.S
     * @createDate 2019/11/05
     */
    public Integer updateUserInfo(CloudFaceApiDTO dto) throws Exception{
        return iPropertyAppUserInfoDao.updateUserInfo(dto);
    }

    /**
     * <desc>
     *      查询用户列表
     * <desc/>
     *
     * @param dto
     * @return 用户信息
     * @author Qiang.S
     * @createDate 2019/11/06
     */
    public Page<SDKFaceUserInfoGetVO> getUserInfoForApi(CloudFaceApiDTO dto) throws Exception {
        Page<SDKFaceUserInfoGetVO> page = new Page<>();
        String currentPage = dto.getCurrentPage();
        String pageSize = dto.getPageSize();
        page.getPage().setPageSize(pageSize);
        page.getPage().setCurrentPage(currentPage);

        Map<String, Object> params = MapUtil.objectToMap(dto, false);
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        List<SDKFaceUserInfoGetVO> list = iPropertyAppUserInfoDao.getUserInfoByPage(params);
        if(list!=null && !list.isEmpty()){
            for(SDKFaceUserInfoGetVO vo : list){
                vo.setClientToken(iPropertyAppUserInfoDao.getClientToken(vo.getUserId()));
            }
        }
        page.setRows(list, iPropertyAppUserInfoDao.getUserInfoPageCount(params));
        return page;
    }

    /**
     * <desc>
     *      获取旧用户临时权限信息
     * </desc>
     *
     * @param userId
     * @param projectId
     * @return
     * @author Jiaqi.X
     * @createDate 2019/09/25
     */
    public Map<String,Object> getOldUserTempAuth(String userId,String projectId){
        Map<String,Object> result = new HashMap<>();
        //获取用户门禁临时权限
        String doorAuth = iPropertyUserInfoDao.getDoorTempAuth(userId, projectId);
        String groupDoorAuth = iPropertyUserInfoDao.getDoorGroupAuth(userId,projectId);
        if(StringUtils.isNotBlank(doorAuth) || StringUtils.isNotBlank(groupDoorAuth)) {
            doorAuth = StringHandlerUtil.convertAuth(doorAuth, "8");
            groupDoorAuth = StringHandlerUtil.convertAuth(groupDoorAuth,"8");
            String[] doorAuths = StringHandlerUtil.splitString(doorAuth);
            String[] groupDoorAuths = StringHandlerUtil.splitString(groupDoorAuth);
            Set<String> da = new HashSet<>();
            for(String a : doorAuths){
                da.add(a);
            }
            for(String a : groupDoorAuths){
                da.add(a);
            }
            result.put("doorAuth",StringUtils.join(da,","));
        }
        //获取用户电梯临时权限
        String elevatorAuth = iPropertyUserInfoDao.getElevatorTempAuth(userId,projectId);
        String elevatorGroupAuth = iPropertyUserInfoDao.getElevatorGroupAuth(userId,projectId);
        if(StringUtils.isNotBlank(elevatorAuth) || StringUtils.isNotBlank(elevatorGroupAuth)){
            elevatorAuth = StringHandlerUtil.convertAuth(elevatorAuth,"1");
            elevatorGroupAuth = StringHandlerUtil.convertAuth(elevatorGroupAuth,"1");
            if(StringUtils.isNotBlank(elevatorGroupAuth)){
                Set<String> elevatorSet = new HashSet<>();
                String[] elevatorStr = StringHandlerUtil.splitString(elevatorAuth);
                String[] elevatorGroupStr = StringHandlerUtil.splitString(elevatorGroupAuth);
                for(String str : elevatorStr){
                    elevatorSet.add(str);
                }
                for(String groupStr : elevatorGroupStr){
                    elevatorSet.add(groupStr);
                }
                elevatorAuth = StringUtils.join(elevatorSet,",");
            }
            result.put("elevatorAuth",elevatorAuth);
        }
        //获取用户云对讲临时权限
        String talkAuth = iPropertyUserInfoDao.getCloudTalkTempAuth(userId,projectId);
        if(StringUtils.isNotBlank(talkAuth)){
            talkAuth = StringHandlerUtil.convertAuth(talkAuth,"8");
            result.put("talkAuth",talkAuth);
        }
        result.put("userId",userId);
        return result;
    }

    /**
     * <desc>
     *      获取修改前的用户名称及标签
     * </desc>
     *
     * @return
     * @author Juguang.S
     * @createDate 2020/05/20
     */
    public Map<String,Object> getOldUserInfo(String userId,String projectId){
        return iPropertyUserInfoDao.getOldUserInfo(userId, projectId);
    }

    /**
     * <desc>
     * 根据用户id查询用户房间信息用于平板增量数据推送
     * </desc>
     *
     * @param userIds
     * @param projectId
     * @return
     * @author jiaqi.X
     * @createDate 2019/03/20
     */
    @Override
    public List<Map<String, Object>> getUserRoomIdsByUserIdAndProjectId(String[] userIds, String projectId) {
        return iPropertyAppUserInfoDao.getUserRoomIdsByUserIdAndProjectId(userIds,projectId);
    }


    /**
     * <desc>
     *     京东非标-人脸注册-业主
     * </desc>
     *
     * @param params
     * @return
     * @author pengwei
     * @createDate 2020/12/08
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public String jdUserFaceReg(JSONObject params)throws Exception {
        String   phoneNum  =  params.getString("phoneNum");
        String   realName  =  params.getString("realName");
        String   gender  =  params.getString("gender");
        String   projectId  =   params.getString("projectId");
        String openId = params.getString("openId");
        //保存用户数据
        if (StringUtils.isBlank(openId)){
            openId = LogicIdUtil.userBusinessId();
        }
        AppUserGetUserInfoDTO appUserGetUserInfoDTO = new AppUserGetUserInfoDTO();
        appUserGetUserInfoDTO.setUserId(openId);
        //因为目前京东项目没有用到我们这边的手机号，按之前的逻辑如果将用户的手机号入库可能会引起修改了其它正常使用者的账
        // 号，所以京东传入的phoneNum暂时不入库，若有需要，再添加
//        appUserGetUserInfoDTO.setPhoneNum(phoneNum);
        appUserGetUserInfoDTO.setRealName(realName);
        if (StringUtils.isNotBlank(gender)){
            appUserGetUserInfoDTO.setGender(Integer.valueOf(gender));
        }
        appUserGetUserInfoDTO.setProjectId(projectId);

        //保存App用户信息
        AppUserInfoPO appUserInfoPO = null;

        //
//        if (StringUtils.isNotBlank(phoneNum)){
//            Map<String, Object> paramsMap = new HashMap<>();
//            paramsMap.put("projectId", projectId);
//            paramsMap.put("phoneNum", phoneNum);
//            appUserInfoPOS = iPropertyAppUserInfoDao.getUserInfoByPhoneNum(paramsMap);
//        }
        //根据userId查询是否有该用户
        List<AppUserInfoPO> appUserInfoPOS = new ArrayList<>();
        if (StringUtils.isNotBlank(params.getString("openId"))){
            appUserInfoPOS = iPropertyAppUserInfoDao.getUserInfoByUserId(params.getString("openId"));
        }
        if (appUserInfoPOS != null && appUserInfoPOS.size() > 0) {
            //AppUserInfo 已存在.系统中只存在一条住户信息数据。已存在住户再添加时更新部分信息
            appUserInfoPO = appUserInfoPOS.get(0);
            appUserInfoPO.setRealName(appUserGetUserInfoDTO.getRealName());
            appUserInfoPO.setGender(appUserGetUserInfoDTO.getGender());
            iPropertyAppUserInfoDao.update(appUserInfoPO);
        } else {
            //AppUserInfo 不存在
            appUserInfoPO = this.getAppUserInfo(appUserGetUserInfoDTO);
            iPropertyAppUserInfoDao.save(SqlUtil.durableData(appUserInfoPO, PlatformConstants.TABLE_SAVE));
        }

        //保存App用户项目信息
        AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
        appUserProjectPO.setProjectId(projectId);
        appUserProjectPO.setUserId(appUserInfoPO.getUserId());
        //住户项目关系是否已存在。存在则做更新，否则做添加
        boolean userProjectIsExist = false;
        List<AppUserProjectPO> appUserProjectPOS = iPropertyAppUserProjectDao.getUserProject(appUserProjectPO);
        if (appUserProjectPOS != null && appUserProjectPOS.size() > 0) {
            appUserProjectPO = appUserProjectPOS.get(0);
            userProjectIsExist = true;
        }
        appUserProjectPO = this.getAppUserProject(appUserGetUserInfoDTO, appUserProjectPO);
        //住户可能已跟项目产生关系如在审核未通过中删除了
        if (userProjectIsExist) {
              iPropertyAppUserProjectDao.update(appUserProjectPO);
        } else {
              iPropertyAppUserProjectDao.save(SqlUtil.durableData(appUserProjectPO, PlatformConstants.TABLE_SAVE));
        }
        return    appUserInfoPO.getUserId();
    }

    /**
     * <desc>
     *     京东非标-人脸注册-业主物理删除
     * </desc>
     *
     * @param params
     * @return
     * @author pengwei
     * @createDate 2020/12/16
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void jdUserRealDel(@RequestBody JSONObject params)throws Exception{
        //用户id
        String   userId  =  params.getString("userId");
        //项目id
        String   projectId  =  params.getString("projectId");
//        iPropertyAppUserProjectDao.deleteUser(userId);
        iPropertyAppUserProjectDao.deleteUserProject(userId,projectId);
    }


    /**
     * <desc>
     *     京东非标-人脸注册-访客
     * </desc>
     *
     * @param params
     * @return
     * @author pengwei
     * @createDate 2020/12/09
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public String jdVisitorFaceReg(JSONObject argsJson) throws Exception {
        //受访人userId
        String   userId  =  argsJson.getString("openId");
        //受访人姓名
        String   intervieweeName =  argsJson.getString("intervieweeName");
        //访客姓名
        String   visitorName     =  argsJson.getString("visitorName");
        //访客手机号--可传空
        String   visitorPhone  =  argsJson.getString("visitorPhone");
        //访问有效时长
        String   effectiveTime  =  argsJson.getString("effectiveTime");
        //访客事由--可传空
        String   visitorCause =  argsJson.getString("visitorCause");
        //项目id
        String   projectId  =   argsJson.getString("projectId");
        AppUserInfoPO    auip  = new  AppUserInfoPO();
        auip.setUserId(userId);
        auip = iPropertyAppUserInfoDao.getOne(auip);
        if(auip==null){
            //受访者不存在
            return null;
        }
        AppVisitorPassCodeRecordPO passPO=new AppVisitorPassCodeRecordPO();
        passPO.setIntervieweeName(intervieweeName);
        passPO.setCreateTime(new Date());
        passPO.setSource(VisitorSourceTypeEnum.APP.getType());
        passPO.setStartTime(passPO.getCreateTime());
        passPO.setProjectId(projectId);
        //由于在后台配置自定义时间 若时长在25天和30天之间，DateUtil.addCurrentTime 计算结束时间会有问题，故在此做了兼容
        if(Integer.parseInt(effectiveTime)>=36000){
            passPO.setEndTime(DateUtil.getAddDay(passPO.getStartTime(),Integer.valueOf(effectiveTime)/60/24));
        }else{
            passPO.setEndTime(DateUtil.addCurrentTime(passPO.getStartTime(),Integer.valueOf(effectiveTime) * 60 * 1000));
        }
        passPO.setPassId(LogicIdUtil.bussinessId());
        passPO.setVisitorName(visitorName);
        passPO.setVisitorPhone(visitorPhone);
        passPO.setStatus(DataStatusEnum.NORMAL.getType());
        passPO.setUserId(userId);
        passPO.setVisitorCause(visitorCause);
        passPO.setCheckOperator("系统");
        passPO.setCheckStatus(1);
        passPO.setOwnerCheckStatus(1);
        passPO.setCheckTime(new Date());
        passPO.setOwnerCheckTime(new Date());
        passPO.setPassNumber(RandomUtil.getRandomStringBySix(6));
        iPropertyVisitorPassCodeRecordDao.save(SqlUtil.durableData(passPO, PlatformConstants.TABLE_SAVE));
        return passPO.getPassId();
    }

    /**
     * <desc>
     *     京东非标-访客内部更新，不做对外接口
     * </desc>
     *
     * @param params
     * @return
     * @author pengwei
     * @createDate 2020/12/09
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public  Integer jdVisitorUpdate(@RequestBody JSONObject params)throws Exception{
        //通行id
        String  passId  =  params.getString("passId");
        //人脸图片地址
        String  uploadFilePath  =  params.getString("uploadFilePath");
        //访客人脸生成id
        String  vFaceId  =  params.getString("vFaceId");
        return iPropertyVisitorPassCodeRecordDao.setVisitPassFace(passId, uploadFilePath, vFaceId);
    }

    /**
     * <desc>
     *     京东非标-用户修改
     * </desc>
     *
     * @param params
     * @return
     * @author pengwei
     * @createDate 2020/12/10
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public JDResultVO jdUserUpdate(@RequestBody JSONObject params)throws Exception{
        //用户id
        String   userId  =  params.getString("openId");
        //真实姓名
        String   realName  =  params.getString("realName");
        //电话号码
        String   phoneNum  =  params.getString("phoneNum");
        //性别
        String   gender  =  params.getString("gender");
        //项目id
        String   projectId  =  params.getString("projectId");
        JDResultVO checkVo  =  userAndProjectExistsCheck(userId,projectId);
        if(!JDCodEnum.SUCCESS.getCode().equals(checkVo.getCode())){
            return   checkVo;
        }
        if (StringUtils.isNotBlank(phoneNum)){
            Integer   cnt  =   iPropertyAppUserProjectDao.checkAppUserPhoneExists(params);
            if(cnt>0){
                return  new JDResultVO(JDCodEnum.PHONE_NUM_EXISTS_ERROR.getCode());
            }
        }
        //修改App用户信息
        AppUserInfoPO    auip  = new  AppUserInfoPO();
        auip.setUserId(userId);
        auip = iPropertyAppUserInfoDao.getOne(auip);
        auip.setRealName(realName);
        if (StringUtils.isNotBlank(gender)){
            auip.setGender(Integer.valueOf(gender));
        }
        auip.setPhoneNum(phoneNum);
        iPropertyAppUserInfoDao.update(auip);
        return    new JDResultVO(JDCodEnum.SUCCESS.getCode());
    }

    /**
     * <desc>
     *     京东非标-用户逻辑删除
     * </desc>
     *
     * @param params
     * @return
     * @author pengwei
     * @createDate 2020/12/10
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public  JDResultVO jdUserDelete(@RequestBody JSONObject params)throws Exception{
        //用户id
        String   userId  =  params.getString("userId");
        //项目id
        String   projectId  =  params.getString("projectId");
        JDResultVO checkVo  =  userAndProjectExistsCheck(userId,projectId);
        if(!JDCodEnum.SUCCESS.getCode().equals(checkVo.getCode())){
            return   checkVo;
        }
        //修改App用户信息
        AppUserInfoPO    auip  = new  AppUserInfoPO();
        auip.setUserId(userId);
        auip = iPropertyAppUserInfoDao.getOne(auip);
        auip.setStatus(DataStatusEnum.DELETE.getType());
        iPropertyAppUserInfoDao.update(auip);
        return    new JDResultVO(JDCodEnum.SUCCESS.getCode());
    }

    /**
     * <desc>
     *     京东非标-乘梯权限变更
     * </desc>
     *
     * @param params
     * @return
     * @author pengwei
     * @createDate 2020/12/10
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public JDResultVO jdAuthAlter(@RequestBody JSONObject params) throws Exception {
        //获取所有权限相关的平板设备（待更新的和数据库已经存在的并集）
        List<String>   padDeviceUniqueList  = new ArrayList<>();
        String   projectId  =  params.getString("projectId");
        String   userId  =  params.getString("openId");
        //电梯权限列表
        String   elevatorList  =  params.getString("elevatorList");
        JDResultVO checkVo  =  userAndProjectExistsCheck(userId,projectId);
        if(!JDCodEnum.SUCCESS.getCode().equals(checkVo.getCode())){
            return   checkVo;
        }
        if(StringUtils.isNotEmpty(elevatorList)){
            //保存此次传过来的全部旺龙机号List
            List<String>  deviceUniqueList  =  new  ArrayList<>();
            List<String>  jdDeviceIdList  =  new ArrayList<>();
            JSONArray  ja  =  null;
            try {
                ja  =  JSONArray.parseArray(elevatorList);
            } catch (Exception e) {
                LOG.error("京东非标--人脸识别乘梯---权限变更解析异常");
                return   new JDResultVO(JDCodEnum.PARAMETER_INVALID.getCode());
            }
            for(int i=0;i<ja.size();i++){
                  JSONObject   jo  =  ja.getJSONObject(i);
                  String deviceId  =  jo.getString("deviceId");
                  jdDeviceIdList.add(deviceId);
              }
              Map<String,Object>   paramMap  = new HashMap<>();
              paramMap.put("jdDeviceIdList",jdDeviceIdList);
              paramMap.put("projectId",projectId);
              //查询京东机号和旺龙对应的关系
              List<JDCloudElevatorFaceVO>   voList  =     iPropertyDeviceElevatorAuthDao.getJDDeviceIdMapList(paramMap);
              Map<String,String>   jdDeviceIdMapping  =  new HashMap<>();

              //做映射和填充最新全量旺龙机号
              if(voList!=null&& voList.size()>0){
                  for(JDCloudElevatorFaceVO  vo:voList){
                      jdDeviceIdMapping.put(vo.getJdDeviceId(),vo.getDeviceUnique());
                      deviceUniqueList.add(vo.getDeviceUnique());
                  }
              }
              //获取所有的平板设备机号（包括之前的权限和此次变更的并集）
              padDeviceUniqueList   =   this.getPadDeviceUniqueList(params,deviceUniqueList);
            Map<String, String> selectedDeviceAuthMap = new HashMap<>();
            for(int i=0;i<ja.size();i++){
                JSONObject   jo  =  ja.getJSONObject(i);
                String deviceId  =  jo.getString("deviceId");
                String floorNum  =  jo.getString("floorNum");
                String  deviceUnique  =  jdDeviceIdMapping.get(deviceId);
                Map<String,Object>   paramsMap  = new HashMap<>();
                paramsMap.put("deviceUnique",deviceUnique);
                paramsMap.put("floorNumList",Arrays.asList(floorNum.split(",")));
                List<String>   naturalFloorList  =    iPropertyDeviceElevatorAuthDao.getNaturalFloorList(paramsMap);
                //获取电梯起始楼层及结束楼层
                Map<String, Object> minAndMaxFloor = iPropertyDeviceElevatorAuthDao.getMinAndMaxFloor(deviceUnique);
                if (minAndMaxFloor != null) {
                    Integer startFloor = minAndMaxFloor.get("minFloor") == null ? null : Double.valueOf(minAndMaxFloor.get("minFloor").toString()).intValue();
                    Integer endFloor = minAndMaxFloor.get("maxFloor") == null ? null : Double.valueOf(minAndMaxFloor.get("maxFloor").toString()).intValue();
                    if (startFloor != null) {
                        for (String f : naturalFloorList) {
                            if (!(
                                    Integer.valueOf(f) <= endFloor && Integer.valueOf(f) >= startFloor
                                    )) {
                                JDResultVO   jDResultVO = new JDResultVO(JDCodEnum.FLOOR_NUM_ERROR.getCode());
                                jDResultVO.setMessage(new  StringBuilder().append(jDResultVO.getMessage()).append("【").append("设备楼层错误,设备机号：").append(deviceId).append("】").toString());
                                return jDResultVO;
                            }
                        }
                    }
                }
                //做权限转换
                String   naturalFloorsStr  =  Joiner.on(",").join(naturalFloorList);
                String oneDevHexfloorAuth = StringHandlerUtil.getAuthCodeBynNturalFloors(naturalFloorsStr);
                selectedDeviceAuthMap.put(deviceUnique,oneDevHexfloorAuth);
            }
            DeviceElevatorAuthPO  deapo  = convertNewTmpElevatorAuthToMapToPO(selectedDeviceAuthMap);
            saveOrUpdate(deapo,userId,projectId);
        }
        return    new JDResultVO(params.getString("id"),JDCodEnum.SUCCESS.getCode(),padDeviceUniqueList);
    }


    /**
     * <desc>
     *     京东非标-电梯及楼层信息获取
     * </desc>
     *
     * @param params
     * @return
     * @author pengwei
     * @createDate 2020/12/11
     */
    public JDResultVO getAllElevatorInfo(@RequestBody JSONObject params)throws Exception{
        //项目id
        String   projectId  =  params.getString("projectId");
        //用户id
        String   userId  =  params.getString("openId");
        //校验
        JDResultVO checkVo  =  userAndProjectExistsCheck(userId,projectId);
        if(!JDCodEnum.SUCCESS.getCode().equals(checkVo.getCode())){
            return   checkVo;
        }
        //定义结果对象map
        Map<String,Object>    resultMap  =  new HashMap<>();
        //定义结果集
        List<JDCloudElevatorFaceVO>  resultVoList  =  new ArrayList<>();
        //查询权限
        params.put("authSource",DeviceAuthEnum.DEVICEAUTH_SDK.getType());
        params.put("userId", userId);
        List<DeviceElevatorAuthPO> deapos = iPropertyDeviceElevatorAuthDao.getUserDeviceElevatorAuth(params);
        if(deapos!=null&&deapos.size()>0){
            DeviceElevatorAuthPO  deapo   = deapos.get(0);
            String  deviceAuth  =  deapo.getDeviceAuth();
            String  floorAuth   =  deapo.getFloorAuth();
            if(StringUtils.isNotEmpty(deviceAuth)){
                //获取有权限的设备id 多个，号分隔
                String deviceIds = StringHandlerUtil.convertAuth(deviceAuth, "1");
                List<String>   deviceIdList =  Arrays.asList(deviceIds.split(","));
                Map<String,Object>   paramMap  = new HashMap<>();
                paramMap.put("deviceIdList",deviceIdList);
                paramMap.put("projectId",projectId);
                //查询京东机号和旺龙对应的关系
                List<JDCloudElevatorFaceVO>   voList    =   iPropertyDeviceElevatorAuthDao.getJDDeviceIdMapList(paramMap);
                //机号映射
                Map<String,JDCloudElevatorFaceVO>   deviceMapping  =  new HashMap<>();
                if(voList!=null&& voList.size()>0){
                    for(JDCloudElevatorFaceVO vo:voList){
                        deviceMapping.put(vo.getDeviceId(),vo);
                    }

                }
                String[]  floorAuthArr  =  floorAuth.split(",");
                for(int  i=0;i<deviceIdList.size();i++){
                    String deviceId  = deviceIdList.get(i);
                    if(StringUtils.isNotEmpty(deviceId)){
                        String  currentFloorAuth  =  floorAuthArr[i];
                        String  naturalFloorNum   =  StringHandlerUtil.convertFloor(StringHandlerUtil.hexToBinary(currentFloorAuth),"1");
                        List<String>   naturalFloorNumList = Arrays.asList(naturalFloorNum.split(","));
                        JDCloudElevatorFaceVO   vo   =  deviceMapping.get(deviceId);
                        String  jdDeviceId =  vo.getJdDeviceId();
                        vo.setDeviceId(jdDeviceId);
                        String  deviceUnique =  vo.getDeviceUnique();
                        String  logicalFloor    = iAppOldHomeDao.getLogicalFloor(naturalFloorNumList,deviceUnique);
                        String  floorNum        =  iAppOldHomeDao.getFloorNum(naturalFloorNumList,deviceUnique);
                        vo.setLogicalFloor(logicalFloor);
                        vo.setFloorNum(floorNum);
                        resultVoList.add(vo);
                    }
                }
            }
        }
        resultMap.put("elevatorList",resultVoList);
        return  new JDResultVO(params.getString("id"),JDCodEnum.SUCCESS.getCode(),resultMap);
    }

    /**
     * <desc>
     *      获取人员类型id
     * </desc>
     *
     * @param userTypeName 人员类型名称
     * @param projectId 项目id
     * @return 人员类型id
     * @Author Zhu.yj
     * @createDate  2021/4/9
     */
    @Override
    public Integer getUserTypeIdByName(String userTypeName, String projectId) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("userTypeName", userTypeName);
        params.put("projectId", projectId);
        return iPropertyUserInfoDao.getUserTypeIdByName(params);
    }

    /**
     * <desc>
     *      获取用户有关人脸和身份证相关信息
     * </desc>
     *
     * @param userId 用户id
     * @param projectId 项目id
     * @return
     * @Author Juguang.S
     * @createDate  2021/4/20
     */
    public PropertyUserProofAuthInfoGetVO getUserFaceAndIdCardInfo(String userId, String projectId) throws Exception {
        return iPropertyHouseholdRoleDao.getUserFaceAndIdCardInfo(userId, projectId);
    }

    /**
     * <desc>
     *      根据房间id获取房间号
     * </desc>
     *
     * @param roomId 房间id
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/20
     */
    @Override
    public String getRoomNum(String roomId) throws Exception {
        return iPropertyAppUserRoomDao.getRoomNum(roomId);
    }

    /**
     * <desc>
     *      删除用户分组及分组中设备权限
     * </desc>
     *
     * @param projectId 项目id
     * @param userId 用户id
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/22
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Integer deleteUserGroupAuth(String projectId, String userId) throws Exception {
        Map<String, Object> params= new HashMap<>();
        params.put("projectId", projectId);
        params.put("userId", userId);
        //删除用户角色组
        iPropertyHouseholdRoleDao.deleteUserGroup(params);

        //删除用户电梯授权

        return null;
    }

    /**
     * <desc>
     *     京东非标-权限变更到数据库
     * </desc>
     *
     * @param params
     * @return
     * @author pengwei
     * @createDate 2020/12/11
     */
    private  void saveOrUpdate(DeviceElevatorAuthPO deapo,String userId,String projectId) throws  Exception{
        Date date = new Date();
        //获取电梯设备权限
        JSONObject params  =  new JSONObject();
        params.put("userId",userId);
        params.put("projectId",projectId);
        List<DeviceElevatorAuthPO> deapos = iPropertyDeviceElevatorAuthDao.getUserDeviceElevatorAuth(params);
        if(deapos!=null&&deapos.size()>0){
            //修改
            DeviceElevatorAuthPO   deapodb  =   deapos.get(0);
            deapodb.setFloorAuth(deapo.getFloorAuth());
            deapodb.setDeviceAuth(deapo.getDeviceAuth());
            deapodb.setUpdateTime(date);
            deapodb.setUserId(userId);
            deapodb.setProjectId(projectId);
            deapodb.setAuthUserId(userId);
            iPropertyDeviceElevatorAuthDao.update(deapodb);
        }else{
            //新增
            deapo.setUserId(userId);
            deapo.setProjectId(projectId);
            deapo.setValiTime(DateUtil.fomatLongDate("2099-12-31 23:59:59"));
            deapo.setAuthSource(DeviceAuthEnum.DEVICEAUTH_SDK.getType());
            deapo.setAuthUserId(userId);
            deapo.setStatus(DataStatusEnum.NORMAL.getType());
            deapo.setCreateTime(date);
            deapo.setUpdateTime(date);
            iPropertyDeviceElevatorAuthDao.save(SqlUtil.durableData(deapo, PlatformConstants.TABLE_SAVE));
        }
    }

    /**
     * <desc>
     *     判断用户和对应的项目关联是否存在
     * </desc>
     *
     * @param params
     * @return
     * @author pengwei
     * @createDate 2020/12/11
     */
    private   JDResultVO   userAndProjectExistsCheck(String  userId,String projectId){
        //查询app用户项目信息
        AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
        appUserProjectPO.setProjectId(projectId);
        appUserProjectPO.setUserId(userId);
        List<AppUserProjectPO> appUserProjectPOS = iPropertyAppUserProjectDao.getUserProject(appUserProjectPO);
        if (appUserProjectPOS == null || appUserProjectPOS.size() == 0) {
            return new JDResultVO(JDCodEnum.PROJECTID_OR_USERID_ERROR.getCode());
        }
        //查看用户是否存在
        AppUserInfoPO    auip  = new  AppUserInfoPO();
        auip.setUserId(userId);
        auip = iPropertyAppUserInfoDao.getOne(auip);
        if(auip==null){
            return  new JDResultVO(JDCodEnum.USER_DO_NOT_EXISTS_ERROR.getCode());
        }
        return  new JDResultVO(JDCodEnum.SUCCESS.getCode());
    }
    /**
     * <desc>
     *     将设备权限Map.<deviceUnique,floorHexStr> eg <0000031210001,4000000000000000000000000000>转换为存库对象
     * </desc>
     *
     * @param newTmpElevatorAuthMap 设备权限Map.<deviceUnique,floorHexStr> eg <0000031210001,4000000000000000000000000000>
     * @return 物业临时电梯权限数据库对象
     * @author LewisLouis
     * @createDate 2018-01-03
     */
    private DeviceElevatorAuthPO convertNewTmpElevatorAuthToMapToPO(Map<String,String> newTmpElevatorAuthMap){
        Map<String, String> orderedElevatorAuthMapMap = new TreeMap<>(newTmpElevatorAuthMap);
        String binDeviceAuth = StringHandlerUtil.fillString(PlatformConstants.ELEVATOR_NOAUTHNUM,PlatformConstants.ELEVATOR_NOAUTHNUM,PlatformConstants.MAX_ELEVATOR_DEVICEID);
        StringBuffer binDeviceAuthBuffer = new StringBuffer(binDeviceAuth);
        List<String> floorsList = new ArrayList<>();
        for (Map.Entry<String, String> entry : orderedElevatorAuthMapMap.entrySet()) {
            String deviceUnique = entry.getKey();
            Integer devId = StringHandlerUtil.
                    strToIntDef(StringHandlerUtil.copySubStr(deviceUnique,9,4),0);
            //设备在授权设备信息字符串中的位置
            int deviceAuthIndex = devId  -  1;
            binDeviceAuthBuffer.setCharAt(deviceAuthIndex, PlatformConstants.ELEVATOR_AUTHNUM.charAt(0));
            String hexFloorsOfOneDev = entry.getValue();
            floorsList.add(hexFloorsOfOneDev);
        }
        String floorsAuth = Joiner.on(",").join(floorsList);
        DeviceElevatorAuthPO deviceElevatorAuthPO = new DeviceElevatorAuthPO();
        deviceElevatorAuthPO.setDeviceAuth(binDeviceAuthBuffer.toString());
        deviceElevatorAuthPO.setFloorAuth(floorsAuth);
        return deviceElevatorAuthPO;
    }


    /**
     * <desc>
     *      根据用户电梯权限(包括待新增和待删除)找出绑定的平板
     * </desc>
     *
     * @param userId 用户id
     * @param projectId 项目id
     * @param deviceUniqueList 需要变更（覆盖）的权限列表
     * @param  项目id
     * @return
     * @Author  pengwei
     * @createDate  2020/12/15
     */
    private List<String> getPadDeviceUniqueList(JSONObject   params ,List<String>  deviceUniqueList){
        String userId = params.getString("openId");
        params.put("userId", userId);
        String   projectId  =  params.getString("projectId");
        List<String> elevatorDeviceUniqueList = new ArrayList<>();
        List<String> deviceUniques = new ArrayList<>();
        List<DeviceElevatorAuthPO> deapos = iPropertyDeviceElevatorAuthDao.getUserDeviceElevatorAuth(params);
        //解析电梯权限
        String deviceIds = "";
        if (deapos != null && deapos.size() > 0) {
            DeviceElevatorAuthPO deapo = deapos.get(0);
            String deviceAuth = deapo.getDeviceAuth();
            deviceIds  =  StringHandlerUtil.convertAuth(deviceAuth, "1");
        }
        List<String> deviceIdList = StringHandlerUtil.splitStringList(deviceIds);
        if (!deviceIdList.isEmpty()){
            for (String deviceId : deviceIdList){
                elevatorDeviceUniqueList.add(StringHandlerUtil.getDeviceUniqueId(projectId,1, deviceId));
            }
            //根据电梯deviceUnique找出绑定该电梯的平板deviceUnique列表
            elevatorDeviceUniqueList.addAll(deviceUniqueList);
            params.put("list",elevatorDeviceUniqueList);
            deviceUniques = iPropertyDeviceElevatorAuthDao.getBindElevatorPadList(params);
        }
        return deviceUniques;
    }


    /**
     * <desc>
     *      删除审核未通过的用户
     * </desc>
     *
     * @param userRemoveDTOS 用户id
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/28
     */
    @Override
    public Integer removeUnPassedUser(List<AppUnCheckUserRemoveDTO> userRemoveDTOS, String projectId) throws Exception {
        Date nowTime =new Date();
        List<AppUserRoomPO> appUserRoomPOS =new ArrayList<>();
        for (AppUnCheckUserRemoveDTO userRemoveDTO : userRemoveDTOS){
            List<String> roomIdList = StringHandlerUtil.splitStringList(userRemoveDTO.getRoomIds());
            for (String roomId : roomIdList){
                AppUserRoomPO appUserRoomPO =new AppUserRoomPO();
                appUserRoomPO.setUserId(userRemoveDTO.getUserId());
                appUserRoomPO.setProjectId(projectId);
                appUserRoomPO.setRoomId(roomId);
                appUserRoomPO.setStatus(DataStatusEnum.DELETE.getType());
                appUserRoomPO.setCreateTime(nowTime);
                appUserRoomPOS.add(appUserRoomPO);
            }
        }
        return iPropertyAppUserRoomDao.batchUpdate(appUserRoomPOS);
    }

    /**
     * <desc>
     *      获取用户列表时的附加字段
     * </desc>
     *
     * @param
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/29
     */
    @Override
    public Map<String, Object> getAppendInfo(CheckAppUserDTO checkAppUserDTO) throws Exception {

        Map<String, Object> params = MapUtil.objectToMap(checkAppUserDTO, false);
        Map<String, Object> result = new HashMap<>();
        //待审核住户(此处时间查询是指更新时间)
        params.put("userRoomStatus", AppUserRoomStatusEnum.USERROOM_STATUS_AUDIT.getType());
        //待审核住户(此处时间查询是指更新时间)
        String beginTime = (String) params.get("beginTime");
        if (StringUtils.isNotBlank(beginTime)) {
            params.put("updateBeginTime", beginTime);
            params.remove("beginTime");
        }
        String endTime = (String) params.get("endTime");
        if (StringUtils.isNotBlank(endTime)) {
            params.put("updateEndTime", endTime);
            params.remove("endTime");
        }
        Integer unCheckUserCount = iPropertyAppUserRoomDao.getNotAuditPageCount(params);
        result.put("unCheckUserCount", unCheckUserCount);
        return result;
    }

    /**
     * <desc>
     *      获取用户旧的角色组id（分组id）
     * </desc>
     *
     * @param userId
     * @param projectId
     * @return
     * @Author Zhu.yj
     * @createDate  2021/5/16
     */
    @Override
    public List<String> getOldRoleGroupId(String userId, String projectId) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("projectId", projectId);
        return iPropertyUserInfoDao.getUserRoleGroupIdList(params);
    }

    /**
     * <desc>
     *      根据用房和项目编号查询是否注册了人脸
     * </desc>
     *
     * @param userId
     * @param projectId
     * @return
     * @Author Juguang.S
     * @createDate  2021/06/11
     */
    @Override
    public Integer isFaceUrlByUserIdAndProjectId (String userId, String projectId) throws Exception {
        return iPropertyAppUserRoomDao.isFaceUser(userId,projectId);
    }

    /**
     * <desc>
     *      获取楼栋、单元及房间相关ID
     * <desc/>
     *
     * @param  roomDTO 项目Id
     * @return 楼栋、单元及房间相关ID
     * @Author Juguang.S
     * @createDate 2021/06/15
     */
    @Override
    public AppUserRoomDTO getRoomInfo(AppUserRoomDTO roomDTO) throws Exception{
        return iPropertyAppUserRoomDao.getRoomInfo(roomDTO);
    }

}
